home *** CD-ROM | disk | FTP | other *** search
/ Chip 2003 October / Chip Ekim 2003.iso / prog / tamsurum / tocom / Security Updates / SQL-MSDE-CriticalUpdate_ENU.msi / Hotfix3 / Files / instdist.sql < prev    next >
Encoding:
Text File  |  2002-07-19  |  756.4 KB  |  21,811 lines

  1. /*
  2. ** InstDist.SQL   
  3. **
  4. **
  5. ** Copyright Microsoft, Inc. 1998-2000
  6. ** All Rights Reserved.
  7. */
  8.  
  9.  
  10. if (    (db_id()     = 1)  -- 'master' db
  11.     OR
  12.         is_srvrolemember('sysadmin') <> 1  -- SA
  13.    )
  14.     begin
  15.     raiserror('Error, the ''master'' database cannot be the distribution database.  This ISQL run will terminate now.'
  16.                  ,11,127)  -- State=127 should halt ISQL.EXE
  17.     end
  18.  
  19. if (    (db_id()     = 1)  -- 'master' db
  20.     OR
  21.         is_srvrolemember('sysadmin') <> 1 -- SA
  22.    )
  23.     begin
  24.     raiserror('Minor error, because previous attempt to gently terminate ISQL failed.  Harshly killing spid.'
  25.                  ,22,127) with log   -- SeverityLevel>=19 kills spid.
  26.     end
  27. select 'At top, db_name()=',db_name()
  28.  
  29. go
  30.  
  31.  
  32. declare @dbname sysname
  33. select  @dbname = db_name()
  34. execute('dump transaction ' +@dbname+ ' with no_log')
  35. go
  36. checkpoint
  37.  
  38. go
  39. EXEC dbo.sp_configure 'allow updates', 1
  40. GO
  41. reconfigure with override
  42. GO
  43.  
  44. set ANSI_NULLS off
  45. go
  46.  
  47. --
  48. -- Check and make sure the database has the correct compatibility level
  49. --
  50. declare @dbname sysname
  51.         ,@cmptlevelmaster tinyint
  52.         ,@cmptlevel tinyint
  53.         
  54. select  @dbname = db_name()
  55. select     @cmptlevelmaster = cmptlevel from master.dbo.sysdatabases where name = 'master'
  56. select     @cmptlevel = cmptlevel from master.dbo.sysdatabases where name = @dbname
  57. if (@cmptlevel != @cmptlevelmaster)
  58. begin
  59.     raiserror('Warning: Distribution database ''%s'' has compatibility level of %d. Changing it to %d.'
  60.         ,10, 1, @dbname, @cmptlevel, @cmptlevelmaster)
  61.     exec dbo.sp_dbcmptlevel @dbname, @cmptlevelmaster
  62. end
  63. go
  64.  
  65. /****************************************************************************/
  66. PRINT ''
  67. PRINT 'Creating distribution tables'
  68. PRINT ''
  69. /****************************************************************************/
  70. EXEC dbo.sp_MScreate_dist_tables
  71. go
  72.  
  73. declare @dbname sysname
  74. select  @dbname = db_name()
  75. execute('dump transaction ' +@dbname+ ' with no_log')
  76. go
  77.  
  78. exec dbo.sp_MS_upd_sysobj_category 1  --Capture now_datetime for use below.
  79.  
  80. /****************************************************************************/
  81. PRINT ''
  82. PRINT 'Dropping all distribution stored procedures'
  83. PRINT ''
  84. /****************************************************************************/
  85. IF EXISTS (SELECT * FROM sysobjects WHERE
  86.    name = 'sp_MSadd_repl_command' and type = 'P')
  87.       DROP PROCEDURE sp_MSadd_repl_command
  88.  
  89. IF EXISTS (SELECT * FROM sysobjects WHERE
  90.    name = 'sp_MScheckretention' and type = 'P')
  91.       DROP PROCEDURE sp_MScheckretention
  92.  
  93. IF EXISTS (SELECT * FROM sysobjects WHERE
  94.    name = 'sp_MScheck_Jet_Subscriber' and type = 'P')
  95.       DROP PROCEDURE sp_MScheck_Jet_Subscriber
  96.  
  97. IF EXISTS (SELECT * FROM sysobjects WHERE
  98.    name = 'sp_MSadd_repl_commands27' and type = 'P')
  99.       DROP PROCEDURE sp_MSadd_repl_commands27
  100.  
  101. IF EXISTS (SELECT * FROM sysobjects WHERE
  102.    name = 'sp_MSadd_repl_commands27hp' and type = 'P')
  103.       DROP PROCEDURE sp_MSadd_repl_commands27hp
  104.  
  105. IF EXISTS (SELECT * FROM sysobjects WHERE
  106.    name = 'sp_MSadd_repl_commands27hp6x' and type = 'P')
  107.       DROP PROCEDURE sp_MSadd_repl_commands27hp6x
  108.  
  109. IF EXISTS (SELECT * FROM sysobjects WHERE
  110.    name = 'sp_MSrefresh_anonymous' and type = 'P')
  111.       DROP PROCEDURE sp_MSrefresh_anonymous
  112.       
  113. IF EXISTS (SELECT * FROM sysobjects WHERE
  114.    name = 'sp_MSadd_subscription' and type = 'P')
  115.       DROP PROCEDURE sp_MSadd_subscription
  116.  
  117. IF EXISTS (SELECT * FROM sysobjects WHERE                    
  118.    name = 'sp_MSdrop_subscription' and type = 'P')
  119.       DROP PROCEDURE sp_MSdrop_subscription
  120.  
  121. if exists (select * from sysobjects where 
  122.     type = 'P' and name = 'sp_MSfetchAdjustidentityrange')
  123.     drop procedure sp_MSfetchAdjustidentityrange
  124.  
  125. IF EXISTS (SELECT * FROM sysobjects WHERE   
  126.     name = 'sp_MSupdate_subscription' and type = 'P')
  127.        DROP PROCEDURE sp_MSupdate_subscription
  128.  
  129. IF EXISTS (SELECT * FROM sysobjects WHERE
  130.     name = 'sp_MSget_repl_commands' and type = 'P')
  131.        DROP PROCEDURE sp_MSget_repl_commands
  132.  
  133. IF EXISTS (SELECT * FROM sysobjects WHERE
  134.     name = 'sp_MSget_repl_cmds_anonymous' and type = 'P')
  135.        DROP PROCEDURE sp_MSget_repl_cmds_anonymous
  136.  
  137. IF EXISTS (select * from sysobjects where
  138.    name = 'sp_MSdrop_agent_entry' and type = 'P')
  139.       DROP PROCEDURE sp_MSdrop_agent_entry
  140.       
  141. IF EXISTS (SELECT * FROM sysobjects WHERE
  142.     name = 'sp_MSadd_anonymous_agent' and type = 'P')
  143.        DROP PROCEDURE sp_MSadd_anonymous_agent
  144.  
  145. -- SyncTran
  146.  
  147.  
  148. IF EXISTS (SELECT * FROM sysobjects WHERE
  149.     name = 'sp_MSget_undelivered_commands' and type = 'P')
  150.        DROP PROCEDURE sp_MSget_undelivered_commands
  151.  
  152. IF EXISTS (SELECT * FROM sysobjects WHERE
  153.     name = 'sp_MSget_anonymous_cmds' and type = 'P')
  154.        DROP PROCEDURE sp_MSget_anonymous_cmds
  155.  
  156. IF EXISTS (SELECT * FROM sysobjects WHERE
  157.     name = 'sp_MSget_loopback_cmds' and type = 'P')
  158.        DROP PROCEDURE sp_MSget_loopback_cmds
  159.  
  160. IF EXISTS (SELECT * FROM sysobjects WHERE
  161.     name = 'sp_MSanonymous_status' and type = 'P')
  162.        DROP PROCEDURE sp_MSanonymous_status
  163.  
  164. IF EXISTS (SELECT * FROM sysobjects WHERE
  165.     name = 'sp_MSsubscription_status' and type = 'P')
  166.        DROP PROCEDURE sp_MSsubscription_status
  167. GO    
  168.  
  169. declare @dbname sysname
  170. select  @dbname = db_name()
  171. execute('dump transaction ' +@dbname+ ' with no_log')
  172.  
  173. go
  174.  
  175. IF EXISTS (SELECT * FROM sysobjects WHERE
  176.    name = 'sp_MSget_last_transaction' and type = 'P')
  177.       DROP PROCEDURE sp_MSget_last_transaction
  178.     
  179.  
  180. IF EXISTS (SELECT * FROM sysobjects WHERE
  181.    name = 'sp_MSadd_subscriber_info' and type = 'P')
  182.       DROP PROCEDURE sp_MSadd_subscriber_info
  183.  
  184. IF EXISTS (SELECT * FROM sysobjects WHERE
  185.    name = 'sp_MSadd_subscriber_schedule' and type = 'P')
  186.       DROP PROCEDURE sp_MSadd_subscriber_schedule
  187.  
  188. IF EXISTS (SELECT * FROM sysobjects WHERE
  189.    name = 'sp_MSupdate_subscriber_info' and type = 'P')
  190.       DROP PROCEDURE sp_MSupdate_subscriber_info
  191.  
  192. IF EXISTS (SELECT * FROM sysobjects WHERE
  193.    name = 'sp_MSupdate_subscriber_schedule' and type = 'P')
  194.       DROP PROCEDURE sp_MSupdate_subscriber_schedule
  195.  
  196. IF EXISTS (SELECT * FROM sysobjects WHERE
  197.    name = 'sp_MSdrop_subscriber_info' and type = 'P')
  198.       DROP PROCEDURE sp_MSdrop_subscriber_info
  199.  
  200. IF EXISTS (SELECT * FROM sysobjects WHERE
  201.    name = 'sp_MShelp_subscriber_info' and type = 'P')
  202.       DROP PROCEDURE sp_MShelp_subscriber_info
  203.  
  204. IF EXISTS (select * from sysobjects where
  205.    name = 'sp_MSdistribution_counters' and type = 'P')
  206.       DROP PROCEDURE sp_MSdistribution_counters
  207.  
  208. IF EXISTS (select * from sysobjects where
  209.    name = 'sp_MSremove_published_jobs' and type = 'P')
  210.       DROP PROCEDURE sp_MSremove_published_jobs
  211.  
  212. IF EXISTS (select * from sysobjects where
  213.    name = 'sp_MSset_snapshot_xact_seqno' and type = 'P')
  214.       DROP PROCEDURE sp_MSset_snapshot_xact_seqno
  215.  
  216. IF EXISTS (select * from sysobjects where
  217.    name = 'sp_MSadd_snapshot_history' and type = 'P')
  218.       DROP PROCEDURE sp_MSadd_snapshot_history
  219.  
  220. IF EXISTS (select * from sysobjects where
  221.    name = 'sp_MSadd_logreader_history' and type = 'P')
  222.       DROP PROCEDURE sp_MSadd_logreader_history
  223.  
  224. IF EXISTS (select * from sysobjects where
  225.    name = 'sp_MSadd_distribution_history' and type = 'P')
  226.       DROP PROCEDURE sp_MSadd_distribution_history
  227.  
  228. IF EXISTS (select * from sysobjects where
  229.    name = 'sp_MSdistribution_cleanup' and type = 'P')
  230.       DROP PROCEDURE sp_MSdistribution_cleanup
  231.  
  232. IF EXISTS (select * from sysobjects where
  233.    name = 'sp_MSsubscription_cleanup' and type = 'P')
  234.       DROP PROCEDURE sp_MSsubscription_cleanup
  235.  
  236. IF EXISTS (select * from sysobjects where
  237.    name = 'sp_MSdistribution_delete' and type = 'P')
  238.       DROP PROCEDURE sp_MSdistribution_delete
  239.  
  240. IF EXISTS (select * from sysobjects where
  241.    name = 'sp_MSmaximum_cleanup_seqno' and type = 'P')
  242.       DROP PROCEDURE sp_MSmaximum_cleanup_seqno
  243.  
  244. IF EXISTS (select * from sysobjects where
  245.    name = 'sp_MSreplremoveuncdir' and type = 'P')
  246.       DROP PROCEDURE sp_MSreplremoveuncdir
  247.  
  248. IF EXISTS (select * from sysobjects where
  249.    name = 'sp_MSdrop_snapshot_dirs' and type = 'P')
  250.       DROP PROCEDURE sp_MSdrop_snapshot_dirs
  251.  
  252. IF EXISTS (select * from sysobjects where
  253.    name = 'sp_MSfast_delete_trans' and type = 'P')
  254.       DROP PROCEDURE sp_MSfast_delete_trans
  255.  
  256. IF EXISTS (select * from sysobjects where
  257.    name = 'sp_MSdelete_dodelete' and type = 'P')
  258.       DROP PROCEDURE sp_MSdelete_dodelete
  259.  
  260. IF EXISTS (select * from sysobjects where
  261.    name = 'sp_MSdelete_publisherdb_trans' and type = 'P')
  262.       DROP PROCEDURE sp_MSdelete_publisherdb_trans
  263.  
  264. IF EXISTS (select * from sysobjects where
  265.    name = 'sp_MShistory_cleanup' and type = 'P')
  266.       DROP PROCEDURE sp_MShistory_cleanup
  267.  
  268. IF EXISTS (select * from sysobjects where
  269.    name = 'sp_MSget_repl_version' and type = 'P')
  270.       DROP PROCEDURE sp_MSget_repl_version
  271.  
  272. IF EXISTS (select * from sysobjects where
  273.    name = 'sp_MSenum_subscriptions' and type = 'P')
  274.       DROP PROCEDURE sp_MSenum_subscriptions
  275.  
  276. IF EXISTS (select * from sysobjects where
  277.    name = 'sp_MSIfExistsSubscription' and type = 'P')
  278.       DROP PROCEDURE sp_MSIfExistsSubscription
  279.  
  280. IF EXISTS (select * from sysobjects where
  281.    name = 'sp_MSenum_snapshot' and type = 'P')
  282.       DROP PROCEDURE sp_MSenum_snapshot
  283.       
  284. IF EXISTS (select * from sysobjects where
  285.    name = 'sp_MSadd_merge_anonymous_agent' and type = 'P')
  286.       DROP PROCEDURE sp_MSadd_merge_anonymous_agent
  287.     
  288. IF EXISTS (select * from sysobjects where
  289.    name = 'sp_MSenum_snapshot_s' and type = 'P')
  290.       DROP PROCEDURE sp_MSenum_snapshot_s
  291.  
  292. IF EXISTS (select * from sysobjects where
  293.    name = 'sp_MSenum_snapshot_sd' and type = 'P')
  294.       DROP PROCEDURE sp_MSenum_snapshot_sd
  295.  
  296. IF EXISTS (select * from sysobjects where
  297.    name = 'sp_MSenum_logreader' and type = 'P')
  298.       DROP PROCEDURE sp_MSenum_logreader
  299.  
  300. IF EXISTS (select * from sysobjects where
  301.    name = 'sp_MSenum_logreader_s' and type = 'P')
  302.       DROP PROCEDURE sp_MSenum_logreader_s
  303.  
  304. IF EXISTS (select * from sysobjects where
  305.    name = 'sp_MSenum_logreader_sd' and type = 'P')
  306.       DROP PROCEDURE sp_MSenum_logreader_sd
  307.  
  308. IF EXISTS (select * from sysobjects where
  309.    name = 'sp_MSenum_qreader' and type = 'P')
  310.       DROP PROCEDURE sp_MSenum_qreader
  311.  
  312. IF EXISTS (select * from sysobjects where
  313.    name = 'sp_MSenum_qreader_s' and type = 'P')
  314.       DROP PROCEDURE sp_MSenum_qreader_s
  315.  
  316. IF EXISTS (select * from sysobjects where
  317.    name = 'sp_MSenum_qreader_sd' and type = 'P')
  318.       DROP PROCEDURE sp_MSenum_qreader_sd
  319.  
  320. IF EXISTS (select * from sysobjects where
  321.    name = 'sp_MSenum_distribution' and type = 'P')
  322.       DROP PROCEDURE sp_MSenum_distribution
  323.  
  324. IF EXISTS (select * from sysobjects where
  325.    name = 'sp_MSenum_distribution_s' and type = 'P')
  326.       DROP PROCEDURE sp_MSenum_distribution_s
  327.  
  328. IF EXISTS (SELECT * FROM sysobjects WHERE
  329.    name = 'sp_MShelp_subscription_status' and type = 'P')
  330.       DROP PROCEDURE sp_MShelp_subscription_status
  331.  
  332. IF EXISTS (SELECT * FROM sysobjects WHERE
  333.    name = 'sp_MScleanup_agent_entry' and type = 'P')
  334.       DROP PROCEDURE sp_MScleanup_agent_entry
  335.  
  336. IF EXISTS (select * from sysobjects where
  337.    name = 'sp_MSenum_distribution_sd' and type = 'P')
  338.       DROP PROCEDURE sp_MSenum_distribution_sd
  339.  
  340. IF EXISTS (select * from sysobjects where
  341.    name = 'sp_MSenum_merge' and type = 'P')
  342.       DROP PROCEDURE sp_MSenum_merge
  343.  
  344. IF EXISTS (select * from sysobjects where
  345.    name = 'sp_MSenum_merge_s' and type = 'P')
  346.       DROP PROCEDURE sp_MSenum_merge_s
  347.  
  348. IF EXISTS (select * from sysobjects where
  349.    name = 'sp_MSenum_merge_sd' and type = 'P')
  350.       DROP PROCEDURE sp_MSenum_merge_sd
  351.  
  352. IF EXISTS (select * from sysobjects where
  353.    name = 'sp_MSgetagentoffloadinfo' and type = 'P')
  354.       DROP PROCEDURE sp_MSgetagentoffloadinfo
  355.  
  356. IF EXISTS (select * from sysobjects where
  357.    name = 'sp_MSenableagentoffload' and type = 'P')
  358.       DROP PROCEDURE sp_MSenableagentoffload
  359.  
  360. IF EXISTS (select * from sysobjects where
  361.    name = 'sp_MSdisableagentoffload' and type = 'P')
  362.       DROP PROCEDURE sp_MSdisableagentoffload 
  363.  
  364. IF EXISTS (select * from sysobjects where
  365.    name = 'sp_MSadd_repl_error' and type = 'P')
  366.       DROP PROCEDURE sp_MSadd_repl_error
  367.  
  368. IF EXISTS (select * from sysobjects where
  369.    name = 'sp_MSadd_repl_alert' and type = 'P')
  370.       DROP PROCEDURE sp_MSadd_repl_alert
  371.  
  372. IF EXISTS (select * from sysobjects where
  373.    name = 'sp_MSadd_replmergealert' and type = 'P')
  374.       DROP PROCEDURE sp_MSadd_replmergealert
  375.  
  376. IF EXISTS (select * from sysobjects where
  377.    name = 'sp_MSget_new_errorid' and type = 'P')
  378.       DROP PROCEDURE sp_MSget_new_errorid
  379.  
  380. IF EXISTS (select * from sysobjects where
  381.    name = 'sp_MSget_repl_error' and type = 'P')
  382.       DROP PROCEDURE sp_MSget_repl_error
  383.  
  384. IF EXISTS (select * from sysobjects where
  385.    name = 'sp_MSadd_merge_history' and type = 'P')
  386.       DROP PROCEDURE sp_MSadd_merge_history
  387.  
  388. IF EXISTS (select * from sysobjects where
  389.    name = 'sp_MSdist_activate_auto_sub' and type = 'P')
  390.       DROP PROCEDURE sp_MSdist_activate_auto_sub
  391.  
  392. IF EXISTS (select * from sysobjects where
  393.    name = 'sp_MSlock_auto_sub' and type = 'P')
  394.       DROP PROCEDURE sp_MSlock_auto_sub
  395.  
  396. IF EXISTS (select * from sysobjects where
  397.    name = 'sp_MSget_new_xact_seqno' and type = 'P')
  398.       DROP PROCEDURE sp_MSget_new_xact_seqno
  399.  
  400. IF EXISTS (select * from sysobjects where
  401.    name = 'sp_MSvalidate_distpublisher' and type = 'P')
  402.       DROP PROCEDURE sp_MSvalidate_distpublisher
  403.  
  404. IF EXISTS (select * from sysobjects where
  405.    name = 'sp_MSadd_publication' and type = 'P')
  406.       DROP PROCEDURE sp_MSadd_publication
  407.  
  408. IF EXISTS (select * from sysobjects where
  409.    name = 'sp_MSchange_publication' and type = 'P')
  410.       DROP PROCEDURE sp_MSchange_publication
  411.  
  412. IF EXISTS (select * from sysobjects where
  413.    name = 'sp_MSadd_article' and type = 'P')
  414.       DROP PROCEDURE sp_MSadd_article
  415.  
  416. IF EXISTS (select * from sysobjects where
  417.    name = 'sp_MSchange_article' and type = 'P')
  418.       DROP PROCEDURE sp_MSchange_article
  419.  
  420. IF EXISTS (select * from sysobjects where
  421.    name = 'sp_MSdrop_publication' and type = 'P')
  422.       DROP PROCEDURE sp_MSdrop_publication
  423.  
  424. IF EXISTS (select * from sysobjects where
  425.    name = 'sp_MSdrop_article' and type = 'P')
  426.       DROP PROCEDURE sp_MSdrop_article
  427.  
  428. IF EXISTS (select * from sysobjects where
  429.    name = 'sp_MShelp_publication' and type = 'P')
  430.       DROP PROCEDURE sp_MShelp_publication
  431.  
  432. IF EXISTS (select * from sysobjects where
  433.    name = 'sp_MShelp_article' and type = 'P')
  434.       DROP PROCEDURE sp_MShelp_article
  435.  
  436. IF EXISTS (select * from sysobjects where
  437.    name = 'sp_MShelp_subscription' and type = 'P')
  438.       DROP PROCEDURE sp_MShelp_subscription
  439.  
  440. IF EXISTS (select * from sysobjects where
  441.    name = 'sp_MSadd_subscription_3rd' and type = 'P')
  442.       DROP PROCEDURE sp_MSadd_subscription_3rd
  443.  
  444. IF EXISTS (select * from sysobjects where
  445.    name = 'sp_MSdrop_subscription_3rd' and type = 'P')
  446.       DROP PROCEDURE sp_MSdrop_subscription_3rd
  447.  
  448. IF EXISTS (select * from sysobjects where
  449.    name = 'sp_MSactivate_subscriptions' and type = 'P')
  450.       DROP PROCEDURE sp_MSactivate_subscriptions
  451.  
  452. IF EXISTS (select * from sysobjects where
  453.    name = 'sp_MSrepl_raiserror' and type = 'P')
  454.       DROP PROCEDURE sp_MSrepl_raiserror
  455.  
  456. IF EXISTS (select * from sysobjects where
  457.    name = 'sp_MSadd_merge_subscription' and type = 'P')
  458.       DROP PROCEDURE sp_MSadd_merge_subscription
  459.  
  460. IF EXISTS (select * from sysobjects where
  461.    name = 'sp_MSdrop_merge_subscription' and type = 'P')
  462.       DROP PROCEDURE sp_MSdrop_merge_subscription
  463.  
  464. IF EXISTS (select * from sysobjects where
  465.    name = 'sp_MSenum_merge_subscriptions' and type = 'P')
  466.       DROP PROCEDURE sp_MSenum_merge_subscriptions
  467.  
  468. IF EXISTS (select * from sysobjects where
  469.    name = 'sp_MSadd_snapshot_agent' and type = 'P')
  470.       DROP PROCEDURE sp_MSadd_snapshot_agent
  471.  
  472. IF EXISTS (select * from sysobjects where
  473.    name = 'sp_MSdrop_snapshot_agent' and type = 'P')
  474.       DROP PROCEDURE sp_MSdrop_snapshot_agent
  475.  
  476. IF EXISTS (select * from sysobjects where
  477.    name = 'sp_MSadd_logreader_agent' and type = 'P')
  478.       DROP PROCEDURE sp_MSadd_logreader_agent
  479.  
  480. IF EXISTS (select * from sysobjects where
  481.    name = 'sp_MSdrop_logreader_agent' and type = 'P')
  482.       DROP PROCEDURE sp_MSdrop_logreader_agent
  483.  
  484. IF EXISTS (select * from sysobjects where
  485.    name = 'sp_MSadd_distribution_agent' and type = 'P')
  486.       DROP PROCEDURE sp_MSadd_distribution_agent
  487.  
  488. IF EXISTS (select * from sysobjects where
  489.    name = 'sp_MSdrop_distribution_agent' and type = 'P')
  490.       DROP PROCEDURE sp_MSdrop_distribution_agent
  491.  
  492. IF EXISTS (select * from sysobjects where
  493.    name = 'sp_MSdrop_distribution_agentid' and type = 'P')
  494.       DROP PROCEDURE sp_MSdrop_distribution_agentid
  495.  
  496. IF EXISTS (select * from sysobjects where
  497.    name = 'sp_MSdrop_merge_agentid' and type = 'P')
  498.       DROP PROCEDURE sp_MSdrop_merge_agentid
  499.  
  500. IF EXISTS (select * from sysobjects where
  501.    name = 'sp_MSadd_merge_agent' and type = 'P')
  502.       DROP PROCEDURE sp_MSadd_merge_agent
  503.  
  504. IF EXISTS (select * from sysobjects where
  505.    name = 'sp_MSdrop_merge_agent' and type = 'P')
  506.       DROP PROCEDURE sp_MSdrop_merge_agent
  507.  
  508. IF EXISTS (select * from sysobjects where
  509.    name = 'sp_MSadd_qreader_agent' and type = 'P')
  510.       DROP PROCEDURE sp_MSadd_qreader_agent
  511.  
  512. IF EXISTS (select * from sysobjects where
  513.    name = 'sp_MSadd_qreader_history' and type = 'P')
  514.       DROP PROCEDURE sp_MSadd_qreader_history
  515.  
  516. IF EXISTS (select * from sysobjects where
  517.    name = 'sp_MSdrop_qreader_agent' and type = 'P')
  518.       DROP PROCEDURE sp_MSdrop_qreader_agent
  519.  
  520. IF EXISTS (select * from sysobjects where
  521.    name = 'sp_MSdrop_qreader_history' and type = 'P')
  522.       DROP PROCEDURE sp_MSdrop_qreader_history
  523.  
  524. IF EXISTS (select name from sysobjects where 
  525.    name = 'sp_update_agent_profile' and type = 'P')
  526.     DROP PROCEDURE sp_update_agent_profile
  527.  
  528. IF EXISTS (select name from sysobjects where 
  529.    name = 'sp_MSprofile_in_use' and type = 'P')
  530.     DROP PROCEDURE sp_MSprofile_in_use
  531.  
  532. IF EXISTS (select * from sysobjects where
  533.    name = 'sp_MSreset_subscription' and type = 'P')
  534.       DROP PROCEDURE sp_MSreset_subscription
  535.  
  536. IF EXISTS (select * from sysobjects where
  537.    name = 'sp_MSget_subscription_guid' and type = 'P')
  538.       DROP PROCEDURE sp_MSget_subscription_guid
  539.  
  540. IF EXISTS (select * from sysobjects where
  541.    name = 'sp_MSreset_subscription_seqno' and type = 'P')
  542.       DROP PROCEDURE sp_MSreset_subscription_seqno
  543.  
  544. IF EXISTS (select * from sysobjects where
  545.    name = 'sp_MShelp_profile' and type = 'P')
  546.       DROP PROCEDURE sp_MShelp_profile
  547.  
  548. IF EXISTS (select * from sysobjects where
  549.    name = 'sp_MShelp_snapshot_agentid' and type = 'P')
  550.       DROP PROCEDURE sp_MShelp_snapshot_agentid
  551.  
  552. IF EXISTS (select * from sysobjects where
  553.    name = 'sp_MShelp_logreader_agentid' and type = 'P')
  554.       DROP PROCEDURE sp_MShelp_logreader_agentid
  555.  
  556. IF EXISTS (select * from sysobjects where
  557.    name = 'sp_MShelp_merge_agentid' and type = 'P')
  558.       DROP PROCEDURE sp_MShelp_merge_agentid
  559.  
  560. IF EXISTS (select * from sysobjects where
  561.    name = 'sp_MSenum_replication_status' and type = 'P')
  562.       DROP PROCEDURE sp_MSenum_replication_status
  563.  
  564. IF EXISTS (select * from sysobjects where
  565.    name = 'sp_MSagent_stethoscope' and type = 'P')
  566.       DROP PROCEDURE sp_MSagent_stethoscope
  567.  
  568. IF EXISTS (select * from sysobjects where
  569.    name = 'sp_MSlock_distribution_agent' and type = 'P')
  570.       DROP PROCEDURE sp_MSlock_distribution_agent
  571.  
  572. IF EXISTS (select * from sysobjects where
  573.    name = 'sp_MSdetect_nonlogged_shutdown' and type = 'P')
  574.       DROP PROCEDURE sp_MSdetect_nonlogged_shutdown
  575.  
  576. IF EXISTS (select * from sysobjects where
  577.    name = 'sp_MSdistpublisher_cleanup' and type = 'P')
  578.       DROP PROCEDURE sp_MSdistpublisher_cleanup
  579.  
  580. IF EXISTS (select * from sysobjects where
  581.    name = 'sp_MSpublication_access' and type = 'P')
  582.       DROP PROCEDURE sp_MSpublication_access
  583.  
  584. IF EXISTS (select * from sysobjects where
  585.    name = 'sp_MScheck_pull_access' and type = 'P')
  586.       DROP PROCEDURE sp_MScheck_pull_access
  587.  
  588. GO
  589. IF EXISTS (select * from sysobjects where
  590.    name = 'sp_MSdrop_6x_publication' and type = 'P')
  591.       DROP PROCEDURE sp_MSdrop_6x_publication
  592.  
  593. IF EXISTS (select * from sysobjects where
  594.    name = 'sp_MShelp_distribution_agentid' and type = 'P')
  595.       DROP PROCEDURE sp_MShelp_distribution_agentid
  596. GO
  597.  
  598. IF EXISTS (select * from sysobjects where
  599.    name = 'sp_MScheck_tran_retention' and type = 'P')
  600.       DROP PROCEDURE sp_MScheck_tran_retention
  601. GO
  602.  
  603. IF EXISTS (select * from sysobjects where
  604.    name = 'sp_MSreinit_subscription' and type = 'P')
  605.       DROP PROCEDURE sp_MSreinit_subscription
  606. go
  607.  
  608. IF EXISTS (select * from sysobjects where
  609.    name = 'sp_MSmarkreinit' and type = 'P')
  610.       DROP PROCEDURE sp_MSmarkreinit
  611. go
  612.  
  613. IF EXISTS (select * from sysobjects where
  614.    name = 'sp_browsereplcmds' and type = 'P')
  615.       DROP PROCEDURE sp_browsereplcmds
  616. go
  617.  
  618. IF EXISTS (select * from sysobjects where
  619.    name = 'sp_dumpparamcmd' and type = 'P')
  620.       DROP PROCEDURE sp_dumpparamcmd
  621. go
  622.  
  623. IF EXISTS (select * from sysobjects where
  624.    name = 'sp_MSbrowsesnapshotfolder' and type = 'P')
  625.       DROP PROCEDURE sp_MSbrowsesnapshotfolder
  626. go
  627.  
  628. IF EXISTS (select * from sysobjects where
  629.    name = 'sp_MSquery_syncstates' and type = 'P')
  630.       DROP PROCEDURE sp_MSquery_syncstates
  631. go
  632.  
  633. IF EXISTS (select * from sysobjects where
  634.    name = 'sp_MSset_syncstate' and type = 'P')
  635.       DROP PROCEDURE sp_MSset_syncstate
  636.  
  637. IF EXISTS (select * from sysobjects where
  638.    name = 'sp_MSdist_adjust_identity' and type = 'P')
  639.       DROP PROCEDURE sp_MSdist_adjust_identity
  640.  
  641. IF EXISTS (select * from sysobjects where
  642.    name = 'sp_MSchange_subscription_dts_info' and type = 'P')
  643.       DROP PROCEDURE sp_MSchange_subscription_dts_info
  644.  
  645. IF EXISTS (select * from sysobjects where
  646.    name = 'sp_MSget_subscription_dts_info' and type = 'P')
  647.       DROP PROCEDURE sp_MSget_subscription_dts_info
  648. go
  649.  
  650. IF EXISTS (select * from sysobjects where
  651.    name = 'sp_MSenumdistributionagentproperties' and type = 'P')
  652.       DROP PROCEDURE sp_MSenumdistributionagentproperties
  653.  
  654. IF EXISTS (select * from sysobjects where
  655.    name = 'sp_MSenum_merge_agent_properties' and type = 'P')
  656.       DROP PROCEDURE sp_MSenum_merge_agent_properties
  657.  
  658. IF EXISTS (select * from sysobjects where
  659.    name = 'sp_MSinsert_identity' and type = 'P')
  660.       DROP PROCEDURE sp_MSinsert_identity
  661.  
  662. IF EXISTS (select * from sysobjects where
  663.    name = 'sp_MSadjust_pub_identity' and type = 'P')
  664.       DROP PROCEDURE sp_MSadjust_pub_identity    
  665.  
  666. IF EXISTS (select * from sysobjects where
  667.    name = 'sp_MScheck_pub_identity' and type = 'P')
  668.       DROP PROCEDURE sp_MScheck_pub_identity    
  669.  
  670. IF EXISTS (select * from sysobjects where
  671.    name = 'sp_dropanonymoussubscription' and type = 'P')
  672.       DROP PROCEDURE sp_dropanonymoussubscription
  673.  
  674. IF EXISTS (select * from sysobjects where
  675.    name = 'sp_MSdrop_anonymous_entry' and type = 'P')
  676.       DROP PROCEDURE sp_MSdrop_anonymous_entry
  677.  
  678. IF EXISTS (select * from sysobjects where
  679.    name = 'sp_MSadddynamicsnapshotjobatdistributor' and type = 'P')
  680.       DROP PROCEDURE sp_MSadddynamicsnapshotjobatdistributor
  681.  
  682. IF EXISTS (select * from sysobjects where
  683.    name = 'sp_MSdeleterepljob' and type = 'P')
  684.       DROP PROCEDURE sp_MSdeleterepljob
  685.  
  686. IF EXISTS (select * from sysobjects where
  687.    name = 'sp_MSdeletefoldercontents' and type = 'P')
  688.       DROP PROCEDURE sp_MSdeletefoldercontents
  689.  
  690. IF EXISTS (select * from sysobjects where
  691.    name = 'sp_MSinvalidate_snapshot' and type = 'P')
  692.       DROP PROCEDURE sp_MSinvalidate_snapshot
  693.  
  694. IF EXISTS (select * from sysobjects where
  695.    name = 'sp_MSrepl_init_backup_lsns' and type = 'P')
  696.       DROP PROCEDURE sp_MSrepl_init_backup_lsns
  697.  
  698. IF EXISTS (select * from sysobjects where
  699.    name = 'sp_MSispublicationqueued' and type = 'P')
  700.       DROP PROCEDURE sp_MSispublicationqueued
  701.  
  702. if exists (select * from sysobjects
  703.      where type = 'FN'
  704.             and name = 'fn_MSmask_agent_type')
  705.      drop function dbo.fn_MSmask_agent_type
  706.  
  707. if exists (select * from sysobjects 
  708.         where type = 'P' and
  709.         name = 'sp_MSwritemergeperfcounter')
  710.         drop procedure sp_MSwritemergeperfcounter
  711.  
  712. if exists (select * from sysobjects 
  713.         where type = 'P' and
  714.         name = 'sp_MSlog_agent_cancel')
  715.         drop procedure sp_MSlog_agent_cancel
  716.  
  717. go
  718.  
  719.  
  720. declare @dbname sysname
  721. select  @dbname = db_name()
  722. execute('dump transaction ' +@dbname+ ' with no_log')
  723. go
  724.  
  725. -- This function is used internally by other stored procedures to mark the agent type
  726. -- for anonymous agent before passing it to sp_MSupdate_replication_status, so anonymous
  727. -- agent status can be filtered out from repl monitor. Only distribution agents and merge
  728. -- agents should use this function. 
  729. raiserror(15339,-1,-1,'fn_MSmask_agent_type')
  730. go
  731. create function dbo.fn_MSmask_agent_type(
  732.     @agent_id int,
  733.     @agent_type int
  734.     ) returns int
  735. as
  736. begin
  737.     declare @anonymous_mask int
  738.     select @anonymous_mask = 0x80000000
  739.     if @agent_type = 3 -- If dist agent
  740.     begin
  741.         if exists (select * from MSdistribution_agents where id = @agent_id and 
  742.             subscriber_name is not null)
  743.             select @agent_type = 3 | @anonymous_mask
  744.         else
  745.             select @agent_type = 3 
  746.     end
  747.     else if @agent_type = 4 -- if merge agent
  748.     begin
  749.         if exists (select * from MSmerge_agents where id = @agent_id and 
  750.             subscriber_name is not null)
  751.             select @agent_type = 4 | @anonymous_mask
  752.         else
  753.             select @agent_type = 4 
  754.     end
  755.     -- if other agents, @agent_type will not change.
  756.     return @agent_type
  757. end
  758. go
  759.  
  760. raiserror(15339,-1,-1,'sp_MScheck_pull_access')
  761. GO
  762.  
  763. CREATE PROCEDURE sp_MScheck_pull_access (
  764.     @agent_id int = 0,
  765.     @agent_type int = 0, -- 0 is tran; 1 is merge
  766.     @publication_id int = 0
  767.         ) AS
  768.  
  769.     declare @retcode int
  770.  
  771.     -- sysadmin or db_owner have access
  772.     if is_srvrolemember('sysadmin') = 1 or 
  773.         is_member('db_owner') = 1
  774.         return 0
  775.  
  776.     -- Need login_time to uniquely identify a connection.
  777.     declare @login_time datetime
  778.     select @login_time = login_time from master..sysprocesses where spid = @@spid
  779.  
  780.     -- For merge change to use publication_id
  781.     if @agent_id <> 0 and @agent_type = 1
  782.     begin
  783.         select @publication_id = p.publication_id from
  784.                 MSmerge_agents a, MSpublications p where
  785.                 a.id = @agent_id and
  786.                 a.publisher_id = p.publisher_id and
  787.                 a.publisher_db = p.publisher_db and
  788.                 a.publication = p.publication
  789.         select @agent_id = 0
  790.     end
  791.  
  792.     -- In cache, return success
  793.     if exists (select * from tempdb.dbo.MSdistributor_access where 
  794.         spid = @@spid and
  795.         login_time = @login_time and
  796.         db_id = db_id() and
  797.         (publication_id = @publication_id and
  798.         agent_id = @agent_id and
  799.         agent_type = @agent_type) or
  800.         -- All 0s is used by sp_MSadd_repl_error, which just require the 
  801.         -- login to be in cache regardless of the publication id and agent_id.
  802.         -- This means that once a agent get into the distribution db, it
  803.         -- can add any error.
  804.         (@publication_id = 0 and @agent_id = 0 and @agent_type = 0))
  805.         return (0)
  806.  
  807.     -- Cover sp_MSadd_repl_error case
  808.     if @publication_id = 0 and @agent_id = 0 and @agent_type = 0
  809.     begin
  810.         RAISERROR (14126, 11, -1)
  811.         return (1)
  812.     end
  813.  
  814.     declare @isntname bit
  815.     declare @offensive_pub_id int
  816.  
  817.     -- Check to see if the login is NT login
  818.     select @isntname = isntname from master..syslogins where
  819.         sid = suser_sid()
  820.     -- If the login does not exists, check to see if the login is a NT login that
  821.     -- has access to the server.
  822.     if @isntname is null
  823.     begin
  824.         -- If it is an NT login
  825.         if suser_sid() is not null
  826.             select @isntname = 1
  827.         -- If it is not an NT login
  828.         else
  829.             select @isntname = 0
  830.     end
  831.  
  832.     -- Check security based on agent_id
  833.     -- We know it is distribution agent. See above.
  834.     if @agent_id <> 0 
  835.     begin
  836.         select top 1 @offensive_pub_id = s.publication_id from MSsubscriptions s where 
  837.             s.agent_id = @agent_id and
  838.             not exists (select * from MSpublication_access l where
  839.                 l.publication_id = s.publication_id and
  840.             -- Current login has no access
  841.             (suser_sid(l.login) = suser_sid() or (@isntname = 1 and exists 
  842.                 (select * from master..syslogins where 
  843.                     sid = suser_sid(l.login) and isntgroup = 1 and is_member(l.login) = 1))))
  844.         
  845.         if @offensive_pub_id is not null
  846.             goto NO_ACCESS
  847.     end
  848.     -- Check security based on publication_id
  849.     else
  850.     begin
  851.         declare @publisher_id smallint
  852.     
  853.         if not exists (select * from MSpublication_access l where
  854.             l.publication_id = @publication_id and
  855.             (suser_sid(l.login) = suser_sid() or (@isntname = 1 and exists 
  856.                 (select * from master..syslogins where 
  857.                     sid = suser_sid(l.login) and isntgroup = 1 and is_member(l.login) = 1))))
  858.         begin
  859.             select @offensive_pub_id = @publication_id
  860.             goto NO_ACCESS
  861.         end
  862.     end
  863.  
  864.     -- If we are here, we know that the connection has access and is not in the cache
  865.     -- add it in to the cache.
  866.         
  867.     -- Clear the cache to keep it small.
  868.     exec @retcode = dbo.sp_MSflush_access_cache
  869.     if @retcode <> 0 or @@error <> 0
  870.         return (1)
  871.         
  872.  
  873.     insert tempdb.dbo.MSdistributor_access
  874.         (spid, db_id, agent_id, agent_type, publication_id, login_time) values
  875.         (@@spid, db_id(), @agent_id, @agent_type, @publication_id, @login_time)
  876.  
  877.     if @@error <> 0
  878.         return (1)
  879.  
  880.     return (0)
  881.  
  882. NO_ACCESS:
  883.  
  884.     -- We don't have access if we reach here, return error
  885.     declare @login sysname
  886.     select @login = suser_sname(suser_sid())
  887.     declare @publication sysname
  888.     select @publication = publication from MSpublications where publication_id = @offensive_pub_id
  889.     raiserror(21049, 16, -1, @login, @publication);
  890.     return(1)
  891.  
  892. GO
  893.  
  894.  
  895. raiserror(15339,-1,-1,'sp_MSquery_syncstates')
  896. GO
  897. create procedure sp_MSquery_syncstates
  898. @publisher_id smallint, 
  899. @publisher_db sysname
  900. as
  901.     declare @retcode int
  902.  
  903.     -- note:  obtain publisher_id via call to sp_MSvalidate_distpublisher
  904.  
  905.     select publication_id from MSsync_states 
  906.     where publisher_id = @publisher_id 
  907.     and publisher_db = @publisher_db
  908.  
  909. go
  910.  
  911.  
  912. raiserror(15339,-1,-1,'sp_MSset_syncstate')
  913. GO
  914. create procedure sp_MSset_syncstate
  915. @publisher_id smallint, 
  916. @publisher_db sysname, 
  917. @article_id int, 
  918. @sync_state int,  
  919. @xact_seqno varbinary(16)
  920. as
  921.  
  922. declare @publication_id int
  923.  
  924. select top 1 @publication_id = s.publication_id 
  925. from MSsubscriptions s
  926. where 
  927. s.publisher_id = @publisher_id and
  928. s.publisher_db = @publisher_db and
  929. s.article_id = @article_id     and
  930. s.subscription_seqno < @xact_seqno
  931.  
  932.  
  933. if @publication_id is not null
  934. begin
  935.     if( @sync_state = 1 )
  936.     begin
  937.         if not exists( select * from MSsync_states 
  938.                        where publisher_id = @publisher_id and
  939.                        publisher_db = @publisher_db and
  940.                        publication_id = @publication_id )
  941.         begin
  942.             insert into MSsync_states( publisher_id, publisher_db, publication_id )
  943.             values( @publisher_id, @publisher_db, @publication_id )
  944.         end
  945.     end
  946.     else if @sync_state = 0 
  947.     begin
  948.         
  949.         delete MSsync_states 
  950.         where 
  951.         publisher_id = @publisher_id and
  952.         publisher_db = @publisher_db and
  953.         publication_id = @publication_id 
  954.  
  955.         -- activate the subscription(s) so the distribution agent can start processing
  956.         declare @automatic int
  957.         declare @active int    
  958.         declare @initiated int
  959.  
  960.         select @automatic = 1
  961.         select @active = 2
  962.         select @initiated = 3
  963.  
  964.         -- set status to active, ss_cplt_seqno = commit LSN of xact containing
  965.         -- syncdone token.  
  966.         --
  967.         -- VERY IMPORTANT:  We can only do this because we know that the publisher
  968.         -- tables are locked in the same transaction that writes the SYNCDONE token.
  969.         -- If the tables were NOT locked, we could get into a situation where data
  970.         -- in the table was changed and committed between the time the SYNCDONE token was
  971.         -- written and the time the SYNCDONE xact was committed.  This would cause the
  972.         -- logreader to replicate the xact with no compensation records, but the advance
  973.         -- of the ss_cplt_seqno would cause the dist to skip that command since only commands
  974.         -- with the snapshot bit set will be processed if they are <= ss_cplt_seqno.
  975.         --
  976.         update MSsubscriptions 
  977.         set status = @active,
  978.             subscription_time = getdate(),
  979.             ss_cplt_seqno = @xact_seqno        
  980.         where
  981.             publisher_id = @publisher_id and
  982.             publisher_db = @publisher_db and
  983.             publication_id = @publication_id and
  984.             sync_type = @automatic and
  985.             status in( @initiated )
  986.     end
  987. end
  988. go
  989.  
  990. raiserror(15339,-1,-1,'sp_MSadd_repl_command')
  991. go
  992. CREATE PROCEDURE sp_MSadd_repl_command
  993. @publisher_id smallint = NULL,
  994. @publisher_db sysname,
  995. @xact_id varbinary(16) = 0x0,
  996. @xact_seqno varbinary(16) = 0x0,
  997. @originator sysname = NULL,
  998. @originator_db sysname = NULL,
  999. @article_id int = NULL,
  1000. @command_id int = 1,
  1001. @type int = NULL,
  1002. @partial_command bit = NULL,
  1003. @command varbinary(1024) = NULL,
  1004. @publisher sysname = NULL
  1005.  
  1006.  
  1007. AS
  1008.  
  1009.    SET NOCOUNT ON
  1010.  
  1011.    DECLARE @date datetime
  1012.    DECLARE @publisher_database_id int
  1013.    declare @originator_id int
  1014.  
  1015.    SELECT @date = GETDATE()
  1016.  
  1017.    if @publisher_id is NULL
  1018.         select @publisher_id = srvid from master..sysservers where
  1019.             UPPER(srvname) = UPPER(@publisher)
  1020.  
  1021.     -- Get publisher database id.
  1022.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  1023.         publisher_db = @publisher_db
  1024.     
  1025.    /* 
  1026.    ** To minimize contention, snapshot does not include this SP call
  1027.    ** inside a transaction. We have to insert to MSrepl_transactions table
  1028.    ** first to ensure clean up stored precedures to work, which only use 
  1029.    ** MSrepl_transactions table but NOT MSrepl_commands table to find transactions
  1030.    ** to be deleted.
  1031.    */
  1032.  
  1033.    IF @command_id = 1
  1034.    BEGIN
  1035.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1036.          @xact_id,  @xact_seqno, @date)
  1037.       IF @@ERROR <> 0
  1038.          RETURN 1
  1039.    END
  1040.  
  1041.    IF @command IS NOT NULL
  1042.    begin
  1043.       if @originator <> N'' and @originator_db <> N'' and @originator is not null and @originator_db is not null 
  1044.       begin
  1045.         set @originator_id = null select @originator_id = id from MSrepl_originators where
  1046.             publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@originator) and
  1047.             dbname = @originator_db
  1048.         if @originator_id is null
  1049.         begin
  1050.             insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1051.                 (@publisher_database_id, @originator, @originator_db)
  1052.             select @originator_id = @@identity
  1053.         end
  1054.       end
  1055.       else
  1056.         select @originator_id = 0
  1057.       
  1058.  
  1059.       if( @type in( 37,38 ) )
  1060.       begin
  1061.             declare @syncstat int
  1062.           select @syncstat = 38 - @type
  1063.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @article_id, @syncstat, @xact_seqno 
  1064.       end
  1065.  
  1066.       INSERT INTO MSrepl_commands VALUES (@publisher_database_id, @xact_seqno,
  1067.         @type, @article_id, @originator_id, @command_id, @partial_command, @command)
  1068.     end
  1069.  
  1070.     IF @@ERROR <> 0
  1071.       RETURN (1)
  1072.  
  1073. GO  
  1074.  
  1075.  
  1076. raiserror(15339,-1,-1,'sp_MSadd_repl_commands27')
  1077. GO
  1078. CREATE PROCEDURE sp_MSadd_repl_commands27
  1079. @publisher_id smallint,
  1080. @publisher_db sysname,
  1081. @xact_id varbinary(16) = 0x0,
  1082. @xact_seqno varbinary(16) = 0x0,
  1083. @originator sysname,
  1084. @originator_db sysname,
  1085. @article_id int,
  1086. @command_id int,
  1087. @type int = 0,
  1088. @partial_command bit,
  1089. @command varbinary(1024),
  1090.  
  1091. @1xact_id varbinary(16) = 0x0,
  1092.  
  1093. @1xact_seqno varbinary(16) = 0x0,
  1094. @1originator sysname = NULL,
  1095. @1originator_db sysname = NULL,
  1096. @1article_id int = 0,
  1097. @1command_id int = 0,
  1098. @1type int = 0,
  1099. @1partial_command bit = 0,
  1100. @1command varbinary(1024) = NULL,
  1101.  
  1102. @2xact_id varbinary(16) = 0x0,
  1103.  
  1104. @2xact_seqno varbinary(16) = 0x0,
  1105. @2originator sysname = NULL,
  1106. @2originator_db sysname = NULL,
  1107. @2article_id int = 0,
  1108. @2command_id int = 0,
  1109. @2type int = 0,
  1110. @2partial_command bit = 0,
  1111. @2command varbinary(1024) = NULL,
  1112.  
  1113. @3xact_id varbinary(16) = 0x0,
  1114.  
  1115. @3xact_seqno varbinary(16) = 0x0,
  1116. @3originator sysname = NULL,
  1117. @3originator_db sysname = NULL,
  1118. @3article_id int = 0,
  1119. @3command_id int = 0,
  1120. @3type int = 0,
  1121. @3partial_command bit = 0,
  1122. @3command varbinary(1024) = NULL,
  1123.  
  1124. @4xact_id varbinary(16) = 0x0,
  1125.  
  1126. @4xact_seqno varbinary(16) = 0x0,
  1127. @4originator sysname = NULL,
  1128. @4originator_db sysname = NULL,
  1129. @4article_id int = 0,
  1130. @4command_id int = 0,
  1131. @4type int = 0,
  1132. @4partial_command bit = 0,
  1133. @4command varbinary(1024) = NULL,
  1134.  
  1135. @5xact_id varbinary(16) = 0x0,
  1136.  
  1137. @5xact_seqno varbinary(16) = 0x0,
  1138. @5originator sysname = NULL,
  1139. @5originator_db sysname = NULL,
  1140. @5article_id int = 0,
  1141. @5command_id int = 0,
  1142. @5type int = 0,
  1143. @5partial_command bit = 0,
  1144. @5command varbinary(1024) = NULL,
  1145.  
  1146. @6xact_id varbinary(16) = 0x0,
  1147.  
  1148. @6xact_seqno varbinary(16) = 0x0,
  1149. @6originator sysname = NULL,
  1150. @6originator_db sysname = NULL,
  1151. @6article_id int = 0,
  1152. @6command_id int = 0,
  1153. @6type int = 0,
  1154. @6partial_command bit = 0,
  1155. @6command varbinary(1024) = NULL,
  1156.  
  1157. @7xact_id varbinary(16) = 0x0,
  1158.  
  1159. @7xact_seqno varbinary(16) = 0x0,
  1160. @7originator sysname = NULL,
  1161. @7originator_db sysname = NULL,
  1162. @7article_id int = 0,
  1163. @7command_id int = 0,
  1164. @7type int = 0,
  1165. @7partial_command bit = 0,
  1166. @7command varbinary(1024) = NULL,
  1167.  
  1168. @8xact_id varbinary(16) = 0x0,
  1169.  
  1170. @8xact_seqno varbinary(16) = 0x0,
  1171. @8originator sysname = NULL,
  1172. @8originator_db sysname = NULL,
  1173. @8article_id int = 0,
  1174. @8command_id int = 0,
  1175. @8type int = 0,
  1176. @8partial_command bit = 0,
  1177. @8command varbinary(1024) = NULL,
  1178.  
  1179. @9xact_id varbinary(16) = 0x0,
  1180.  
  1181. @9xact_seqno varbinary(16) = 0x0,
  1182. @9originator sysname = NULL,
  1183. @9originator_db sysname = NULL,
  1184. @9article_id int = 0,
  1185. @9command_id int = 0,
  1186. @9type int = 0,
  1187. @9partial_command bit = 0,
  1188. @9command varbinary(1024) = NULL,
  1189.  
  1190. @10xact_id varbinary(16) = 0x0,
  1191.  
  1192. @10xact_seqno varbinary(16) = 0x0,
  1193. @10originator sysname = NULL,
  1194. @10originator_db sysname = NULL,
  1195. @10article_id int = 0,
  1196. @10command_id int = 0,
  1197. @10type int = 0,
  1198. @10partial_command bit = 0,
  1199. @10command varbinary(1024) = NULL,
  1200.  
  1201. @11xact_id varbinary(16) = 0x0,
  1202.  
  1203. @11xact_seqno varbinary(16) = 0x0,
  1204. @11originator sysname = NULL,
  1205. @11originator_db sysname = NULL,
  1206. @11article_id int = 0,
  1207. @11command_id int = 0,
  1208. @11type int = 0,
  1209. @11partial_command bit = 0,
  1210. @11command varbinary(1024) = NULL,
  1211.  
  1212. @12xact_id varbinary(16) = 0x0,
  1213.  
  1214. @12xact_seqno varbinary(16) = 0x0,
  1215. @12originator sysname = NULL,
  1216. @12originator_db sysname = NULL,
  1217. @12article_id int = 0,
  1218. @12command_id int = 0,
  1219. @12type int = 0,
  1220. @12partial_command bit = 0,
  1221. @12command varbinary(1024) = NULL,
  1222.  
  1223. @13xact_id varbinary(16) = 0x0,
  1224.  
  1225. @13xact_seqno varbinary(16) = 0x0,
  1226. @13originator sysname = NULL,
  1227. @13originator_db sysname = NULL,
  1228. @13article_id int = 0,
  1229. @13command_id int = 0,
  1230. @13type int = 0,
  1231. @13partial_command bit = 0,
  1232. @13command varbinary(1024) = NULL,
  1233.  
  1234. @14xact_id varbinary(16) = 0x0,
  1235.  
  1236. @14xact_seqno varbinary(16) = 0x0,
  1237. @14originator sysname = NULL,
  1238. @14originator_db sysname = NULL,
  1239. @14article_id int = 0,
  1240. @14command_id int = 0,
  1241. @14type int = 0,
  1242. @14partial_command bit = 0,
  1243. @14command varbinary(1024) = NULL,
  1244.  
  1245. @15xact_id varbinary(16) = 0x0,
  1246.  
  1247. @15xact_seqno varbinary(16) = 0x0,
  1248. @15originator sysname = NULL,
  1249. @15originator_db sysname = NULL,
  1250. @15article_id int = 0,
  1251. @15command_id int = 0,
  1252. @15type int = 0,
  1253. @15partial_command bit = 0,
  1254. @15command varbinary(1024) = NULL,
  1255.  
  1256. @16xact_id varbinary(16) = 0x0,
  1257.  
  1258. @16xact_seqno varbinary(16) = 0x0,
  1259. @16originator sysname = NULL,
  1260. @16originator_db sysname = NULL,
  1261. @16article_id int = 0,
  1262. @16command_id int = 0,
  1263. @16type int = 0,
  1264. @16partial_command bit = 0,
  1265. @16command varbinary(1024) = NULL,
  1266.  
  1267. @17xact_id varbinary(16) = 0x0,
  1268.  
  1269. @17xact_seqno varbinary(16) = 0x0,
  1270. @17originator sysname = NULL,
  1271. @17originator_db sysname = NULL,
  1272. @17article_id int = 0,
  1273. @17command_id int = 0,
  1274. @17type int = 0,
  1275. @17partial_command bit = 0,
  1276. @17command varbinary(1024) = NULL,
  1277.  
  1278. @18xact_id varbinary(16) = 0x0,
  1279.  
  1280. @18xact_seqno varbinary(16) = 0x0,
  1281. @18originator sysname = NULL,
  1282. @18originator_db sysname = NULL,
  1283. @18article_id int = 0,
  1284. @18command_id int = 0,
  1285. @18type int = 0,
  1286. @18partial_command bit = 0,
  1287. @18command varbinary(1024) = NULL,
  1288.  
  1289. @19xact_id varbinary(16) = 0x0,
  1290.  
  1291. @19xact_seqno varbinary(16) = 0x0,
  1292. @19originator sysname = NULL,
  1293. @19originator_db sysname = NULL,
  1294. @19article_id int = 0,
  1295. @19command_id int = 0,
  1296. @19type int = 0,
  1297. @19partial_command bit = 0,
  1298. @19command varbinary(1024) = NULL,
  1299.  
  1300. @20xact_id varbinary(16) = 0x0,
  1301.  
  1302. @20xact_seqno varbinary(16) = 0x0,
  1303. @20originator sysname = NULL,
  1304. @20originator_db sysname = NULL,
  1305. @20article_id int = 0,
  1306. @20command_id int = 0,
  1307. @20type int = 0,
  1308. @20partial_command bit = 0,
  1309. @20command varbinary(1024) = NULL,
  1310.  
  1311. @21xact_id varbinary(16) = 0x0,
  1312.  
  1313. @21xact_seqno varbinary(16) = 0x0,
  1314. @21originator sysname = NULL,
  1315. @21originator_db sysname = NULL,
  1316. @21article_id int = 0,
  1317. @21command_id int = 0,
  1318. @21type int = 0,
  1319. @21partial_command bit = 0,
  1320. @21command varbinary(1024) = NULL,
  1321.  
  1322. @22xact_id varbinary(16) = 0x0,
  1323.  
  1324. @22xact_seqno varbinary(16) = 0x0,
  1325. @22originator sysname = NULL,
  1326. @22originator_db sysname = NULL,
  1327. @22article_id int = 0,
  1328. @22command_id int = 0,
  1329. @22type int = 0,
  1330. @22partial_command bit = 0,
  1331. @22command varbinary(1024) = NULL,
  1332.  
  1333. @23xact_id varbinary(16) = 0x0,
  1334.  
  1335. @23xact_seqno varbinary(16) = 0x0,
  1336. @23originator sysname = NULL,
  1337. @23originator_db sysname = NULL,
  1338. @23article_id int = 0,
  1339. @23command_id int = 0,
  1340. @23type int = 0,
  1341. @23partial_command bit = 0,
  1342. @23command varbinary(1024) = NULL,
  1343.  
  1344. @24xact_id varbinary(16) = 0x0,
  1345.  
  1346. @24xact_seqno varbinary(16) = 0x0,
  1347. @24originator sysname = NULL,
  1348. @24originator_db sysname = NULL,
  1349. @24article_id int = 0,
  1350. @24command_id int = 0,
  1351. @24type int = 0,
  1352. @24partial_command bit = 0,
  1353. @24command varbinary(1024) = NULL,
  1354.  
  1355. @25xact_id varbinary(16) = 0x0,
  1356.  
  1357. @25xact_seqno varbinary(16) = 0x0,
  1358. @25originator sysname = NULL,
  1359. @25originator_db sysname = NULL,
  1360. @25article_id int = 0,
  1361. @25command_id int = 0,
  1362. @25type int = 0,
  1363. @25partial_command bit = 0,
  1364. @25command varbinary(1024) = NULL,
  1365.  
  1366. @26xact_id varbinary(16) = 0x0,
  1367.  
  1368. @26xact_seqno varbinary(16) = 0x0,
  1369. @26originator sysname = NULL,
  1370. @26originator_db sysname = NULL,
  1371. @26article_id int = 0,
  1372. @26command_id int = 0,
  1373. @26type int = 0,
  1374. @26partial_command bit = 0,
  1375. @26command varbinary(1024) = NULL
  1376.  
  1377. AS
  1378.  
  1379.     SET NOCOUNT ON
  1380.  
  1381.     DECLARE @publisher_database_id int
  1382.     DECLARE @date datetime
  1383.     declare @originator_id int
  1384.     declare @syncstat int
  1385.  
  1386.     SELECT @date = GETDATE()
  1387.  
  1388.     -- Get publisher database id.
  1389.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  1390.         publisher_db = @publisher_db
  1391.     
  1392.     -- First insert into MS_repl_transactions
  1393.     IF @command_id = 1
  1394.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1395.          @xact_id,  @xact_seqno, @date)
  1396.  
  1397.     IF @1xact_id = 0x0
  1398.       goto INSERT_CMDS
  1399.     IF @1command_id = 1
  1400.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1401.          @1xact_id,  @1xact_seqno, @date)
  1402.  
  1403.     IF @2xact_id = 0x0
  1404.       goto INSERT_CMDS
  1405.     IF @2command_id = 1
  1406.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1407.          @2xact_id,  @2xact_seqno, @date)
  1408.     
  1409.     IF @3xact_id = 0x0
  1410.       goto INSERT_CMDS
  1411.     IF @3command_id = 1
  1412.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1413.          @3xact_id,  @3xact_seqno, @date)
  1414.  
  1415.     IF @4xact_id = 0x0
  1416.       goto INSERT_CMDS
  1417.     IF @4command_id = 1
  1418.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1419.         @4xact_id,  @4xact_seqno, @date)
  1420.  
  1421.     IF @5xact_id = 0x0
  1422.       goto INSERT_CMDS
  1423.  
  1424.     IF @5command_id = 1
  1425.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1426.          @5xact_id,  @5xact_seqno, @date)
  1427.  
  1428.     IF @6xact_id = 0x0
  1429.       goto INSERT_CMDS
  1430.     IF @6command_id = 1
  1431.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1432.          @6xact_id,  @6xact_seqno, @date)
  1433.  
  1434.     IF @7xact_id = 0x0
  1435.       goto INSERT_CMDS
  1436.     IF @7command_id = 1
  1437.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1438.          @7xact_id,  @7xact_seqno, @date)
  1439.  
  1440.     IF @8xact_id = 0x0
  1441.       goto INSERT_CMDS
  1442.     IF @8command_id = 1
  1443.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1444.          @8xact_id,  @8xact_seqno, @date)
  1445.  
  1446.     IF @9xact_id = 0x0
  1447.       goto INSERT_CMDS
  1448.     IF @9command_id = 1
  1449.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1450.          @9xact_id,  @9xact_seqno, @date)
  1451.  
  1452.     IF @10xact_id = 0x0
  1453.       goto INSERT_CMDS
  1454.     IF @10command_id = 1
  1455.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1456.          @10xact_id,  @10xact_seqno, @date)
  1457.  
  1458.     IF @11xact_id = 0x0
  1459.       goto INSERT_CMDS
  1460.     IF @11command_id = 1
  1461.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1462.          @11xact_id,  @11xact_seqno, @date)
  1463.  
  1464.     IF @12xact_id = 0x0
  1465.       goto INSERT_CMDS
  1466.     IF @12command_id = 1
  1467.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1468.          @12xact_id,  @12xact_seqno, @date)
  1469.  
  1470.     IF @13xact_id = 0x0
  1471.       goto INSERT_CMDS
  1472.     IF @13command_id = 1
  1473.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1474.          @13xact_id,  @13xact_seqno, @date)
  1475.  
  1476.     IF @14xact_id = 0x0
  1477.       goto INSERT_CMDS
  1478.     IF @14command_id = 1
  1479.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1480.          @14xact_id,  @14xact_seqno, @date)
  1481.  
  1482.     IF @15xact_id = 0x0
  1483.       goto INSERT_CMDS
  1484.     IF @15command_id = 1
  1485.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1486.          @15xact_id,  @15xact_seqno, @date)
  1487.  
  1488.     IF @16xact_id = 0x0
  1489.       goto INSERT_CMDS
  1490.     IF @16command_id = 1
  1491.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1492.          @16xact_id,  @16xact_seqno, @date)
  1493.  
  1494.     IF @17xact_id = 0x0
  1495.       goto INSERT_CMDS
  1496.     IF @17command_id = 1
  1497.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1498.          @17xact_id,  @17xact_seqno, @date)
  1499.  
  1500.     IF @18xact_id = 0x0
  1501.       goto INSERT_CMDS
  1502.     IF @18command_id = 1
  1503.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1504.          @18xact_id,  @18xact_seqno, @date)
  1505.  
  1506.     IF @19xact_id = 0x0
  1507.       goto INSERT_CMDS
  1508.     IF @19command_id = 1
  1509.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1510.          @19xact_id,  @19xact_seqno, @date)
  1511.  
  1512.     IF @20xact_id = 0x0
  1513.       goto INSERT_CMDS
  1514.     IF @20command_id = 1
  1515.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1516.          @20xact_id,  @20xact_seqno, @date)
  1517.  
  1518.     IF @21xact_id = 0x0
  1519.       goto INSERT_CMDS
  1520.     IF @21command_id = 1
  1521.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1522.          @21xact_id,  @21xact_seqno, @date)
  1523.  
  1524.     IF @22xact_id = 0x0
  1525.       goto INSERT_CMDS
  1526.     IF @22command_id = 1
  1527.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1528.          @22xact_id,  @22xact_seqno, @date)
  1529.  
  1530.     IF @23xact_id = 0x0
  1531.       goto INSERT_CMDS
  1532.     IF @23command_id = 1
  1533.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1534.          @23xact_id,  @23xact_seqno, @date)
  1535.  
  1536.     IF @24xact_id = 0x0
  1537.       goto INSERT_CMDS
  1538.     IF @24command_id = 1
  1539.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1540.          @24xact_id,  @24xact_seqno, @date)
  1541.  
  1542.     IF @25xact_id = 0x0
  1543.       goto INSERT_CMDS
  1544.     IF @25command_id = 1
  1545.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1546.          @25xact_id,  @25xact_seqno, @date)
  1547.  
  1548.     IF @26xact_id = 0x0
  1549.       goto INSERT_CMDS
  1550.     IF @26command_id = 1
  1551.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1552.          @26xact_id,  @26xact_seqno, @date)
  1553.  
  1554. INSERT_CMDS:
  1555.  
  1556.     -- Get the originator_id for the first command 
  1557.     if @originator <> N'' and @originator_db <> N'' and @originator is not null and @originator_db is not null 
  1558.     begin 
  1559.         set @originator_id = null select @originator_id = id from MSrepl_originators where
  1560.             publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@originator) and
  1561.             dbname = @originator_db
  1562.         if @originator_id is null
  1563.         begin
  1564.             insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1565.                 (@publisher_database_id, @originator, @originator_db)
  1566.             select @originator_id = @@identity
  1567.         end
  1568.     end
  1569.     else
  1570.         select @originator_id = 0
  1571.  
  1572.     -- Now insert into MSrepl_commands
  1573.     IF @command IS NOT NULL
  1574.     begin
  1575.         if( @type in( 37,38 ) )
  1576.         begin
  1577.           select @syncstat = 38 - @type
  1578.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @article_id, @syncstat, @xact_seqno
  1579.         end
  1580.  
  1581.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1582.             @xact_seqno,@type, @article_id, 
  1583.             @originator_id, 
  1584.             @command_id, @partial_command, @command)
  1585.     end
  1586.  
  1587.     IF @1xact_id = 0x0
  1588.       return
  1589.  
  1590.     IF @1command IS NOT NULL
  1591.     begin
  1592.             if @1originator <> N'' and @1originator_db <> N'' and @1originator is not null and @1originator_db is not null 
  1593.             begin 
  1594.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1595.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@1originator) and
  1596.                     dbname = @1originator_db
  1597.                 if @originator_id is null
  1598.                 begin
  1599.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1600.                         (@publisher_database_id, @1originator, @1originator_db)
  1601.                     select @originator_id = @@identity
  1602.                 end
  1603.             end
  1604.             else
  1605.                 select @originator_id = 0
  1606.     
  1607.         if( @type in( 37,38 ) )
  1608.         begin
  1609.           select @syncstat = 38 - @1type
  1610.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @1article_id, @syncstat, @1xact_seqno
  1611.         end
  1612.  
  1613.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1614.             @1xact_seqno,@1type, @1article_id, 
  1615.             @originator_id, 
  1616.             @1command_id, @1partial_command, @1command)
  1617.     end
  1618.  
  1619.     IF @2xact_id = 0x0
  1620.       return
  1621.     IF @2command IS NOT NULL
  1622.     begin
  1623.             if @2originator <> N'' and @2originator_db <> N'' and @2originator is not null and @2originator_db is not null 
  1624.             begin 
  1625.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1626.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@2originator) and
  1627.                     dbname = @2originator_db
  1628.                 if @originator_id is null
  1629.                 begin
  1630.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1631.                         (@publisher_database_id, @2originator, @2originator_db)
  1632.                     select @originator_id = @@identity
  1633.                 end
  1634.             end
  1635.             else
  1636.                 select @originator_id = 0
  1637.     
  1638.         if( @type in( 37,38 ) )
  1639.         begin
  1640.           select @syncstat = 38 - @2type
  1641.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @2article_id, @syncstat, @2xact_seqno 
  1642.         end
  1643.  
  1644.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1645.             @2xact_seqno,@2type, @2article_id, 
  1646.             @originator_id, 
  1647.             @2command_id, @2partial_command, @2command)
  1648.     end
  1649.  
  1650.     IF @3xact_id = 0x0
  1651.       return
  1652.     IF @3command IS NOT NULL
  1653.     begin
  1654.             if @3originator <> N'' and @3originator_db <> N'' and @3originator is not null and @3originator_db is not null 
  1655.             begin 
  1656.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1657.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@3originator) and
  1658.                     dbname = @3originator_db
  1659.                 if @originator_id is null
  1660.                 begin
  1661.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1662.                         (@publisher_database_id, @3originator, @3originator_db)
  1663.                     select @originator_id = @@identity
  1664.                 end
  1665.             end
  1666.             else
  1667.                 select @originator_id = 0
  1668.  
  1669.         if( @type in( 37,38 ) )
  1670.         begin
  1671.           select @syncstat = 38 - @3type
  1672.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @3article_id, @syncstat, @3xact_seqno 
  1673.         end
  1674.     
  1675.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1676.             @3xact_seqno,@3type, @3article_id, 
  1677.             @originator_id, 
  1678.             @3command_id, @3partial_command, @3command)
  1679.     end
  1680.  
  1681.     IF @4xact_id = 0x0
  1682.       return
  1683.     IF @4command IS NOT NULL
  1684.     begin
  1685.             if @4originator <> N'' and @4originator_db <> N'' and @4originator is not null and @4originator_db is not null 
  1686.             begin 
  1687.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1688.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@4originator) and
  1689.                     dbname = @4originator_db
  1690.                 if @originator_id is null
  1691.                 begin
  1692.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1693.                         (@publisher_database_id, @4originator, @4originator_db)
  1694.                     select @originator_id = @@identity
  1695.                 end
  1696.             end
  1697.             else
  1698.                 select @originator_id = 0
  1699.  
  1700.         if( @type in( 37,38 ) )
  1701.         begin
  1702.           select @syncstat = 38 - @4type
  1703.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @4article_id, @syncstat, @4xact_seqno 
  1704.         end
  1705.     
  1706.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1707.             @4xact_seqno,@4type, @4article_id, 
  1708.             @originator_id, 
  1709.             @4command_id, @4partial_command, @4command)
  1710.     end
  1711.  
  1712.     IF @5xact_id = 0x0
  1713.       return
  1714.     IF @5command IS NOT NULL
  1715.     begin
  1716.             if @5originator <> N'' and @5originator_db <> N'' and @5originator is not null and @5originator_db is not null 
  1717.             begin 
  1718.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1719.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@5originator) and
  1720.                     dbname = @5originator_db
  1721.                 if @originator_id is null
  1722.                 begin
  1723.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1724.                         (@publisher_database_id, @5originator, @5originator_db)
  1725.                     select @originator_id = @@identity
  1726.                 end
  1727.             end
  1728.             else
  1729.                 select @originator_id = 0
  1730.     
  1731.         if( @type in( 37,38 ) )
  1732.         begin
  1733.           select @syncstat = 38 - @5type
  1734.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @5article_id, @syncstat, @5xact_seqno 
  1735.         end
  1736.  
  1737.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1738.             @5xact_seqno,@5type, @5article_id, 
  1739.             @originator_id, 
  1740.             @5command_id, @5partial_command, @5command)
  1741.     end
  1742.  
  1743.     IF @6xact_id = 0x0
  1744.       return
  1745.     IF @6command IS NOT NULL
  1746.     begin
  1747.             if @6originator <> N'' and @6originator_db <> N'' and @6originator is not null and @6originator_db is not null 
  1748.             begin 
  1749.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1750.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@6originator) and
  1751.                     dbname = @6originator_db
  1752.                 if @originator_id is null
  1753.                 begin
  1754.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1755.                         (@publisher_database_id, @6originator, @6originator_db)
  1756.                     select @originator_id = @@identity
  1757.                 end
  1758.             end
  1759.             else
  1760.                 select @originator_id = 0
  1761.  
  1762.         if( @type in( 37,38 ) )
  1763.         begin
  1764.           select @syncstat = 38 - @6type
  1765.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @6article_id, @syncstat, @6xact_seqno 
  1766.         end
  1767.     
  1768.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1769.             @6xact_seqno,@6type, @6article_id, 
  1770.             @originator_id, 
  1771.             @6command_id, @6partial_command, @6command)
  1772.     end
  1773.  
  1774.     IF @7xact_id = 0x0
  1775.       return
  1776.     IF @7command IS NOT NULL
  1777.     begin
  1778.             if @7originator <> N'' and @7originator_db <> N'' and @7originator is not null and @7originator_db is not null 
  1779.             begin 
  1780.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1781.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@7originator) and
  1782.                     dbname = @7originator_db
  1783.                 if @originator_id is null
  1784.                 begin
  1785.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1786.                         (@publisher_database_id, @7originator, @7originator_db)
  1787.                     select @originator_id = @@identity
  1788.                 end
  1789.             end
  1790.             else
  1791.                 select @originator_id = 0
  1792.     
  1793.         if( @type in( 37,38 ) )
  1794.         begin
  1795.           select @syncstat = 38 - @7type
  1796.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @7article_id, @syncstat, @7xact_seqno 
  1797.         end
  1798.  
  1799.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1800.             @7xact_seqno,@7type, @7article_id, 
  1801.             @originator_id, 
  1802.             @7command_id, @7partial_command, @7command)
  1803.     end
  1804.  
  1805.     IF @8xact_id = 0x0
  1806.       return
  1807.     IF @8command IS NOT NULL
  1808.     begin
  1809.             if @8originator <> N'' and @8originator_db <> N'' and @8originator is not null and @8originator_db is not null 
  1810.             begin 
  1811.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1812.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@8originator) and
  1813.                     dbname = @8originator_db
  1814.                 if @originator_id is null
  1815.                 begin
  1816.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1817.                         (@publisher_database_id, @8originator, @8originator_db)
  1818.                     select @originator_id = @@identity
  1819.                 end
  1820.             end
  1821.             else
  1822.                 select @originator_id = 0
  1823.     
  1824.         if( @type in( 37,38 ) )
  1825.         begin
  1826.           select @syncstat = 38 - @8type
  1827.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @8article_id, @syncstat, @8xact_seqno 
  1828.         end
  1829.  
  1830.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1831.             @8xact_seqno,@8type, @8article_id, 
  1832.             @originator_id, 
  1833.             @8command_id, @8partial_command, @8command)
  1834.     end
  1835.  
  1836.     IF @9xact_id = 0x0
  1837.       return
  1838.     IF @9command IS NOT NULL
  1839.     begin
  1840.             if @9originator <> N'' and @9originator_db <> N'' and @9originator is not null and @9originator_db is not null 
  1841.             begin 
  1842.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1843.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@9originator) and
  1844.                     dbname = @9originator_db
  1845.                 if @originator_id is null
  1846.                 begin
  1847.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1848.                         (@publisher_database_id, @9originator, @9originator_db)
  1849.                     select @originator_id = @@identity
  1850.                 end
  1851.             end
  1852.             else
  1853.                 select @originator_id = 0
  1854.     
  1855.         if( @type in( 37,38 ) )
  1856.         begin
  1857.           select @syncstat = 38 - @9type
  1858.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @9article_id, @syncstat, @9xact_seqno 
  1859.         end
  1860.  
  1861.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1862.             @9xact_seqno,@9type, @9article_id, 
  1863.             @originator_id, 
  1864.             @9command_id, @9partial_command, @9command)
  1865.     end
  1866.  
  1867.     IF @10xact_id = 0x0
  1868.       return
  1869.     IF @10command IS NOT NULL
  1870.     begin
  1871.             if @10originator <> N'' and @10originator_db <> N'' and @10originator is not null and @10originator_db is not null 
  1872.             begin 
  1873.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1874.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@10originator) and
  1875.                     dbname = @10originator_db
  1876.                 if @originator_id is null
  1877.                 begin
  1878.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1879.                         (@publisher_database_id, @10originator, @10originator_db)
  1880.                     select @originator_id = @@identity
  1881.                 end
  1882.             end
  1883.             else
  1884.                 select @originator_id = 0
  1885.     
  1886.         if( @type in( 37,38 ) )
  1887.         begin
  1888.           select @syncstat = 38 - @10type
  1889.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @10article_id, @syncstat, @10xact_seqno 
  1890.         end
  1891.  
  1892.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1893.             @10xact_seqno,@10type, @10article_id, 
  1894.             @originator_id, 
  1895.             @10command_id, @10partial_command, @10command)
  1896.     end
  1897.  
  1898.     IF @11xact_id = 0x0
  1899.       return
  1900.     IF @11command IS NOT NULL
  1901.     begin
  1902.             if @11originator <> N'' and @11originator_db <> N'' and @11originator is not null and @11originator_db is not null 
  1903.             begin 
  1904.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1905.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@11originator) and
  1906.                     dbname = @11originator_db
  1907.                 if @originator_id is null
  1908.                 begin
  1909.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1910.                         (@publisher_database_id, @11originator, @11originator_db)
  1911.                     select @originator_id = @@identity
  1912.                 end
  1913.             end
  1914.             else
  1915.                 select @originator_id = 0
  1916.     
  1917.         if( @type in( 37,38 ) )
  1918.         begin
  1919.           select @syncstat = 38 - @11type
  1920.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @11article_id, @syncstat, @11xact_seqno 
  1921.         end
  1922.  
  1923.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1924.             @11xact_seqno,@11type, @11article_id, 
  1925.             @originator_id, 
  1926.             @11command_id, @11partial_command, @11command)
  1927.     end
  1928.  
  1929.     IF @12xact_id = 0x0
  1930.       return
  1931.     IF @12command IS NOT NULL
  1932.     begin
  1933.             if @12originator <> N'' and @12originator_db <> N'' and @12originator is not null and @12originator_db is not null 
  1934.             begin 
  1935.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1936.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@12originator) and
  1937.                     dbname = @12originator_db
  1938.                 if @originator_id is null
  1939.                 begin
  1940.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1941.                         (@publisher_database_id, @12originator, @12originator_db)
  1942.                     select @originator_id = @@identity
  1943.                 end
  1944.             end
  1945.             else
  1946.                 select @originator_id = 0
  1947.     
  1948.         if( @type in( 37,38 ) )
  1949.         begin
  1950.           select @syncstat = 38 - @12type
  1951.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @12article_id, @syncstat, @12xact_seqno 
  1952.         end
  1953.  
  1954.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1955.             @12xact_seqno,@12type, @12article_id, 
  1956.             @originator_id, 
  1957.             @12command_id, @12partial_command, @12command)
  1958.     end
  1959.  
  1960.  
  1961.     IF @13xact_id = 0x0
  1962.       return
  1963.     IF @13command IS NOT NULL
  1964.     begin
  1965.             if @13originator <> N'' and @13originator_db <> N'' and @13originator is not null and @13originator_db is not null 
  1966.             begin 
  1967.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1968.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@13originator) and
  1969.                     dbname = @13originator_db
  1970.                 if @originator_id is null
  1971.                 begin
  1972.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1973.                         (@publisher_database_id, @13originator, @13originator_db)
  1974.                     select @originator_id = @@identity
  1975.                 end
  1976.             end
  1977.             else
  1978.                 select @originator_id = 0
  1979.     
  1980.         if( @type in( 37,38 ) )
  1981.         begin
  1982.           select @syncstat = 38 - @13type
  1983.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @13article_id, @syncstat, @13xact_seqno 
  1984.         end
  1985.  
  1986.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1987.             @13xact_seqno,@13type, @13article_id, 
  1988.             @originator_id, 
  1989.             @13command_id, @13partial_command, @13command)
  1990.     end
  1991.  
  1992.     IF @14xact_id = 0x0
  1993.       return
  1994.     IF @14command IS NOT NULL
  1995.     begin
  1996.             if @14originator <> N'' and @14originator_db <> N'' and @14originator is not null and @14originator_db is not null 
  1997.             begin 
  1998.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1999.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@14originator) and
  2000.                     dbname = @14originator_db
  2001.                 if @originator_id is null
  2002.                 begin
  2003.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2004.                         (@publisher_database_id, @14originator, @14originator_db)
  2005.                     select @originator_id = @@identity
  2006.                 end
  2007.             end
  2008.             else
  2009.                 select @originator_id = 0
  2010.     
  2011.         if( @type in( 37,38 ) )
  2012.         begin
  2013.           select @syncstat = 38 - @14type
  2014.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @14article_id, @syncstat, @14xact_seqno 
  2015.         end
  2016.  
  2017.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2018.             @14xact_seqno,@14type, @14article_id, 
  2019.             @originator_id, 
  2020.             @14command_id, @14partial_command, @14command)
  2021.     end
  2022.  
  2023.  
  2024.     IF @15xact_id = 0x0
  2025.       return
  2026.     IF @15command IS NOT NULL
  2027.     begin
  2028.             if @15originator <> N'' and @15originator_db <> N'' and @15originator is not null and @15originator_db is not null 
  2029.             begin 
  2030.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2031.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@15originator) and
  2032.                     dbname = @15originator_db
  2033.                 if @originator_id is null
  2034.                 begin
  2035.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2036.                         (@publisher_database_id, @15originator, @15originator_db)
  2037.                     select @originator_id = @@identity
  2038.                 end
  2039.             end
  2040.             else
  2041.                 select @originator_id = 0
  2042.     
  2043.         if( @type in( 37,38 ) )
  2044.         begin
  2045.           select @syncstat = 38 - @15type
  2046.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @15article_id, @syncstat, @15xact_seqno 
  2047.         end
  2048.  
  2049.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2050.             @15xact_seqno,@15type, @15article_id, 
  2051.             @originator_id, 
  2052.             @15command_id, @15partial_command, @15command)
  2053.     end
  2054.  
  2055.     IF @16xact_id = 0x0
  2056.       return
  2057.     IF @16command IS NOT NULL
  2058.     begin
  2059.             if @16originator <> N'' and @16originator_db <> N'' and @16originator is not null and @16originator_db is not null 
  2060.             begin 
  2061.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2062.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@16originator) and
  2063.                     dbname = @16originator_db
  2064.                 if @originator_id is null
  2065.                 begin
  2066.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2067.                         (@publisher_database_id, @16originator, @16originator_db)
  2068.                     select @originator_id = @@identity
  2069.                 end
  2070.             end
  2071.             else
  2072.                 select @originator_id = 0
  2073.     
  2074.         if( @type in( 37,38 ) )
  2075.         begin
  2076.           select @syncstat = 38 - @16type
  2077.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @16article_id, @syncstat, @16xact_seqno 
  2078.         end
  2079.  
  2080.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2081.             @16xact_seqno,@16type, @16article_id, 
  2082.             @originator_id, 
  2083.             @16command_id, @16partial_command, @16command)
  2084.     end
  2085.  
  2086.  
  2087.     IF @17xact_id = 0x0
  2088.       return
  2089.     IF @17command IS NOT NULL
  2090.     begin
  2091.             if @17originator <> N'' and @17originator_db <> N'' and @17originator is not null and @17originator_db is not null 
  2092.             begin 
  2093.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2094.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@17originator) and
  2095.                     dbname = @17originator_db
  2096.                 if @originator_id is null
  2097.                 begin
  2098.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2099.                         (@publisher_database_id, @17originator, @17originator_db)
  2100.                     select @originator_id = @@identity
  2101.                 end
  2102.             end
  2103.             else
  2104.                 select @originator_id = 0
  2105.     
  2106.         if( @type in( 37,38 ) )
  2107.         begin
  2108.           select @syncstat = 38 - @17type
  2109.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @17article_id, @syncstat, @17xact_seqno 
  2110.         end
  2111.  
  2112.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2113.             @17xact_seqno,@17type, @17article_id, 
  2114.             @originator_id, 
  2115.             @17command_id, @17partial_command, @17command)
  2116.     end
  2117.  
  2118.  
  2119.     IF @18xact_id = 0x0
  2120.       return
  2121.     IF @18command IS NOT NULL
  2122.     begin
  2123.             if @18originator <> N'' and @18originator_db <> N'' and @18originator is not null and @18originator_db is not null 
  2124.             begin 
  2125.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2126.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@18originator) and
  2127.                     dbname = @18originator_db
  2128.                 if @originator_id is null
  2129.                 begin
  2130.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2131.                         (@publisher_database_id, @18originator, @18originator_db)
  2132.                     select @originator_id = @@identity
  2133.                 end
  2134.             end
  2135.             else
  2136.                 select @originator_id = 0
  2137.     
  2138.         if( @type in( 37,38 ) )
  2139.         begin
  2140.           select @syncstat = 38 - @18type
  2141.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @18article_id, @syncstat, @18xact_seqno 
  2142.         end
  2143.  
  2144.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2145.             @18xact_seqno,@18type, @18article_id, 
  2146.             @originator_id, 
  2147.             @18command_id, @18partial_command, @18command)
  2148.     end
  2149.  
  2150.  
  2151.     IF @19xact_id = 0x0
  2152.       return
  2153.     IF @19command IS NOT NULL
  2154.     begin
  2155.             if @19originator <> N'' and @19originator_db <> N'' and @19originator is not null and @19originator_db is not null 
  2156.             begin 
  2157.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2158.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@19originator) and
  2159.                     dbname = @19originator_db
  2160.                 if @originator_id is null
  2161.                 begin
  2162.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2163.                         (@publisher_database_id, @19originator, @19originator_db)
  2164.                     select @originator_id = @@identity
  2165.                 end
  2166.             end
  2167.             else
  2168.                 select @originator_id = 0
  2169.     
  2170.         if( @type in( 37,38 ) )
  2171.         begin
  2172.           select @syncstat = 38 - @19type
  2173.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @19article_id, @syncstat, @19xact_seqno 
  2174.         end
  2175.  
  2176.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2177.             @19xact_seqno,@19type, @19article_id, 
  2178.             @originator_id, 
  2179.             @19command_id, @19partial_command, @19command)
  2180.     end
  2181.  
  2182.  
  2183.     IF @20xact_id = 0x0
  2184.       return
  2185.     IF @20command IS NOT NULL
  2186.     begin
  2187.             if @20originator <> N'' and @20originator_db <> N'' and @20originator is not null and @20originator_db is not null 
  2188.             begin 
  2189.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2190.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@20originator) and
  2191.                     dbname = @20originator_db
  2192.                 if @originator_id is null
  2193.                 begin
  2194.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2195.                         (@publisher_database_id, @20originator, @20originator_db)
  2196.                     select @originator_id = @@identity
  2197.                 end
  2198.             end
  2199.             else
  2200.                 select @originator_id = 0
  2201.     
  2202.         if( @type in( 37,38 ) )
  2203.         begin
  2204.           select @syncstat = 38 - @20type
  2205.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @20article_id, @syncstat, @20xact_seqno 
  2206.         end
  2207.  
  2208.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2209.             @20xact_seqno,@20type, @20article_id, 
  2210.             @originator_id, 
  2211.             @20command_id, @20partial_command, @20command)
  2212.     end
  2213.  
  2214.     IF @21xact_id = 0x0
  2215.       return
  2216.     IF @21command IS NOT NULL
  2217.     begin
  2218.             if @21originator <> N'' and @21originator_db <> N'' and @21originator is not null and @21originator_db is not null 
  2219.             begin 
  2220.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2221.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@21originator) and
  2222.                     dbname = @21originator_db
  2223.                 if @originator_id is null
  2224.                 begin
  2225.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2226.                         (@publisher_database_id, @21originator, @21originator_db)
  2227.                     select @originator_id = @@identity
  2228.                 end
  2229.             end
  2230.             else
  2231.                 select @originator_id = 0
  2232.     
  2233.         if( @type in( 37,38 ) )
  2234.         begin
  2235.           select @syncstat = 38 - @21type
  2236.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @21article_id, @syncstat, @21xact_seqno 
  2237.         end
  2238.  
  2239.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2240.             @21xact_seqno,@21type, @21article_id, 
  2241.             @originator_id, 
  2242.             @21command_id, @21partial_command, @21command)
  2243.     end
  2244.  
  2245.     IF @22xact_id = 0x0
  2246.       return
  2247.     IF @22command IS NOT NULL
  2248.     begin
  2249.             if @22originator <> N'' and @22originator_db <> N'' and @22originator is not null and @22originator_db is not null 
  2250.             begin 
  2251.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2252.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@22originator) and
  2253.                     dbname = @22originator_db
  2254.                 if @originator_id is null
  2255.                 begin
  2256.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2257.                         (@publisher_database_id, @22originator, @22originator_db)
  2258.                     select @originator_id = @@identity
  2259.                 end
  2260.             end
  2261.             else
  2262.                 select @originator_id = 0
  2263.         end
  2264.     
  2265.         if( @type in( 37,38 ) )
  2266.         begin
  2267.           select @syncstat = 38 - @22type
  2268.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @22article_id, @syncstat, @22xact_seqno 
  2269.         end
  2270.  
  2271.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2272.             @22xact_seqno,@22type, @22article_id, 
  2273.             @originator_id, 
  2274.             @22command_id, @22partial_command, @22command)
  2275.  
  2276.  
  2277.     IF @23xact_id = 0x0
  2278.       return
  2279.     IF @23command IS NOT NULL
  2280.     begin
  2281.             if @23originator <> N'' and @23originator_db <> N'' and @23originator is not null and @23originator_db is not null 
  2282.             begin 
  2283.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2284.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@23originator) and
  2285.                     dbname = @23originator_db
  2286.                 if @originator_id is null
  2287.                 begin
  2288.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2289.                         (@publisher_database_id, @23originator, @23originator_db)
  2290.                     select @originator_id = @@identity
  2291.                 end
  2292.             end
  2293.             else
  2294.                 select @originator_id = 0
  2295.     
  2296.         if( @type in( 37,38 ) )
  2297.         begin
  2298.           select @syncstat = 38 - @23type
  2299.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @23article_id, @syncstat, @23xact_seqno 
  2300.         end
  2301.  
  2302.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2303.             @23xact_seqno,@23type, @23article_id, 
  2304.             @originator_id, 
  2305.             @23command_id, @23partial_command, @23command)
  2306.     end
  2307.  
  2308.     IF @24xact_id = 0x0
  2309.       return
  2310.     IF @24command IS NOT NULL
  2311.     begin
  2312.             if @24originator <> N'' and @24originator_db <> N'' and @24originator is not null and @24originator_db is not null 
  2313.             begin 
  2314.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2315.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@24originator) and
  2316.                     dbname = @24originator_db
  2317.                 if @originator_id is null
  2318.                 begin
  2319.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2320.                         (@publisher_database_id, @24originator, @24originator_db)
  2321.                     select @originator_id = @@identity
  2322.                 end
  2323.             end
  2324.             else
  2325.                 select @originator_id = 0
  2326.     
  2327.         if( @type in( 37,38 ) )
  2328.         begin
  2329.           select @syncstat = 38 - @24type
  2330.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @24article_id, @syncstat, @24xact_seqno 
  2331.         end
  2332.  
  2333.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2334.             @24xact_seqno,@24type, @24article_id, 
  2335.             @originator_id, 
  2336.             @24command_id, @24partial_command, @24command)
  2337.     end
  2338.  
  2339.  
  2340.     IF @25xact_id = 0x0
  2341.       return
  2342.     IF @25command IS NOT NULL
  2343.     begin
  2344.             if @25originator <> N'' and @25originator_db <> N'' and @25originator is not null and @25originator_db is not null 
  2345.             begin 
  2346.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2347.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@25originator) and
  2348.                     dbname = @25originator_db
  2349.                 if @originator_id is null
  2350.                 begin
  2351.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2352.                         (@publisher_database_id, @25originator, @25originator_db)
  2353.                     select @originator_id = @@identity
  2354.                 end
  2355.             end
  2356.             else
  2357.                 select @originator_id = 0
  2358.     
  2359.         if( @type in( 37,38 ) )
  2360.         begin
  2361.           select @syncstat = 38 - @25type
  2362.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @25article_id, @syncstat, @25xact_seqno 
  2363.         end
  2364.  
  2365.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2366.             @25xact_seqno,@25type, @25article_id, 
  2367.             @originator_id, 
  2368.             @25command_id, @25partial_command, @25command)
  2369.     end
  2370.  
  2371.  
  2372.     IF @26xact_id = 0x0
  2373.       return
  2374.     IF @26command IS NOT NULL
  2375.     begin
  2376.             if @26originator <> N'' and @26originator_db <> N'' and @26originator is not null and @26originator_db is not null 
  2377.             begin 
  2378.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2379.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@26originator) and
  2380.                     dbname = @26originator_db
  2381.                 if @originator_id is null
  2382.                 begin
  2383.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2384.                         (@publisher_database_id, @26originator, @26originator_db)
  2385.                     select @originator_id = @@identity
  2386.                 end
  2387.             end
  2388.             else
  2389.                 select @originator_id = 0
  2390.     
  2391.         if( @type in( 37,38 ) )
  2392.         begin
  2393.           select @syncstat = 38 - @26type
  2394.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @26article_id, @syncstat, @26xact_seqno 
  2395.         end
  2396.  
  2397.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2398.             @26xact_seqno,@26type, @26article_id, 
  2399.             @originator_id, 
  2400.             @26command_id, @26partial_command, @26command)
  2401.     end
  2402.  
  2403.  
  2404.     IF @@ERROR <> 0
  2405.       return (1)
  2406. GO
  2407.  
  2408. raiserror(15339,-1,-1,'sp_MSadd_repl_commands27hp6x')
  2409. GO
  2410.  
  2411. CREATE PROCEDURE sp_MSadd_repl_commands27hp6x
  2412. @publisher_id smallint,
  2413. @publisher_db sysname,
  2414. @data varbinary( 1575 ),
  2415. @1data varbinary(1575) = NULL,
  2416. @2data varbinary(1575) = NULL,
  2417. @3data varbinary(1575) = NULL,
  2418. @4data varbinary(1575) = NULL,
  2419. @5data varbinary(1575) = NULL,
  2420. @6data varbinary(1575) = NULL,
  2421. @7data varbinary(1575) = NULL,
  2422. @8data varbinary(1575) = NULL,
  2423. @9data varbinary(1575) = NULL,
  2424. @10data varbinary(1575) = NULL,
  2425. @11data varbinary(1575) = NULL,
  2426. @12data varbinary(1575) = NULL,
  2427. @13data varbinary(1575) = NULL,
  2428. @14data varbinary(1575) = NULL,
  2429. @15data varbinary(1575) = NULL,
  2430. @16data varbinary(1575) = NULL,
  2431. @17data varbinary(1575) = NULL,
  2432. @18data varbinary(1575) = NULL,
  2433. @19data varbinary(1575) = NULL,
  2434. @20data varbinary(1575) = NULL,
  2435. @21data varbinary(1575) = NULL,
  2436. @22data varbinary(1575) = NULL,
  2437. @23data varbinary(1575) = NULL,
  2438. @24data varbinary(1575) = NULL,
  2439. @25data varbinary(1575) = NULL,
  2440. @26data varbinary(1575) = NULL
  2441. AS
  2442.  
  2443.     SET NOCOUNT ON
  2444.  
  2445.     DECLARE @xact_id    varbinary(10)
  2446.     DECLARE @xact_seqno varbinary(10)
  2447.     DECLARE @article_id int
  2448.     DECLARE @command_id int
  2449.     DECLARE @type       int
  2450.     DECLARE @partial_command bit
  2451.     DECLARE @command    varbinary(1024)
  2452.  
  2453.     DECLARE @originator sysname
  2454.     DECLARE @originator_db sysname
  2455.  
  2456.     DECLARE @publisher_database_id int
  2457.     DECLARE @date datetime
  2458.     declare @originator_id int
  2459.  
  2460.     DECLARE @cmd_data_len  smallint
  2461.     DECLARE @orig_srv_len smallint
  2462.     DECLARE @orig_db_len  smallint
  2463.  
  2464.     SELECT @date = GETDATE()
  2465.  
  2466.     -- Get publisher database id.
  2467.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  2468.         publisher_db = @publisher_db
  2469.  
  2470.     -- First insert into MS_repl_transactions
  2471.     IF convert( int, substring( @data, 25, 4 ) ) = 1
  2472.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2473.          substring( @data, 1, 6 ), substring( @data, 11, 8 ), @date)
  2474.  
  2475.     IF @1data is null
  2476.       goto INSERT_CMDS
  2477.     IF convert( int, substring( @1data, 25, 4 ) ) = 1
  2478.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2479.          substring( @1data, 1, 6 ), substring( @1data, 11, 8 ), @date)
  2480.  
  2481.     IF @2data is null
  2482.       goto INSERT_CMDS
  2483.     IF convert( int, substring( @2data, 25, 4 ) ) = 1
  2484.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2485.          substring( @2data, 1, 6 ), substring( @2data, 11, 8 ), @date)
  2486.     
  2487.     IF @3data is null
  2488.       goto INSERT_CMDS
  2489.     IF convert( int, substring( @3data, 25, 4 ) ) = 1
  2490.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2491.          substring( @3data, 1, 6 ), substring( @3data, 11, 8 ), @date)
  2492.  
  2493.     IF @4data is null
  2494.       goto INSERT_CMDS
  2495.     IF convert( int, substring( @4data, 25, 4 ) ) = 1
  2496.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2497.          substring( @4data, 1, 6 ), substring( @4data, 11, 8 ), @date)
  2498.  
  2499.     IF @5data is null
  2500.       goto INSERT_CMDS
  2501.     IF convert( int, substring( @5data, 25, 4 ) ) = 1
  2502.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2503.          substring( @5data, 1, 6 ), substring( @5data, 11, 8 ), @date)
  2504.  
  2505.     IF @6data is null
  2506.       goto INSERT_CMDS
  2507.     IF convert( int, substring( @6data, 25, 4 ) ) = 1
  2508.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2509.          substring( @6data, 1, 6 ), substring( @6data, 11, 8 ), @date)
  2510.  
  2511.     IF @7data is null
  2512.       goto INSERT_CMDS
  2513.     IF convert( int, substring( @7data, 25, 4 ) ) = 1
  2514.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2515.          substring( @7data, 1, 6 ), substring( @7data, 11, 8 ), @date)
  2516.  
  2517.     IF @8data is null
  2518.       goto INSERT_CMDS
  2519.     IF convert( int, substring( @8data, 25, 4 ) ) = 1
  2520.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2521.          substring( @8data, 1, 6 ), substring( @8data, 11, 8 ), @date)
  2522.  
  2523.     IF @9data is null
  2524.       goto INSERT_CMDS
  2525.     IF convert( int, substring( @9data, 25, 4 ) ) = 1
  2526.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2527.          substring( @9data, 1, 6 ), substring( @9data, 11, 8 ), @date)
  2528.  
  2529.     IF @10data is null
  2530.       goto INSERT_CMDS
  2531.     IF convert( int, substring( @10data, 25, 4 ) ) = 1
  2532.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2533.          substring( @10data, 1, 6 ), substring( @10data, 11, 8 ), @date)
  2534.  
  2535.     IF @11data is null
  2536.       goto INSERT_CMDS
  2537.     IF convert( int, substring( @11data, 25, 4 ) ) = 1
  2538.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2539.          substring( @11data, 1, 6 ), substring( @11data, 11, 8 ), @date)
  2540.  
  2541.     IF @12data is null
  2542.       goto INSERT_CMDS
  2543.     IF convert( int, substring( @12data, 25, 4 ) ) = 1
  2544.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2545.          substring( @12data, 1, 6 ), substring( @12data, 11, 8 ), @date)
  2546.  
  2547.     IF @13data is null
  2548.       goto INSERT_CMDS
  2549.     IF convert( int, substring( @13data, 25, 4 ) ) = 1
  2550.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2551.          substring( @13data, 1, 6 ), substring( @13data, 11, 8 ), @date)
  2552.  
  2553.     IF @14data is null
  2554.       goto INSERT_CMDS
  2555.     IF convert( int, substring( @14data, 25, 4 ) ) = 1
  2556.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2557.          substring( @14data, 1, 6 ), substring( @14data, 11, 8 ), @date)
  2558.  
  2559.     IF @15data is null
  2560.       goto INSERT_CMDS
  2561.     IF convert( int, substring( @15data, 25, 4 ) ) = 1
  2562.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2563.          substring( @15data, 1, 6 ), substring( @15data, 11, 8 ), @date)
  2564.  
  2565.     IF @16data is null
  2566.       goto INSERT_CMDS
  2567.     IF convert( int, substring( @16data, 25, 4 ) ) = 1
  2568.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2569.          substring( @16data, 1, 6 ), substring( @16data, 11, 8 ), @date)
  2570.  
  2571.     IF @17data is null
  2572.       goto INSERT_CMDS
  2573.     IF convert( int, substring( @17data, 25, 4 ) ) = 1
  2574.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2575.          substring( @17data, 1, 6 ), substring( @17data, 11, 8 ), @date)
  2576.  
  2577.     IF @18data is null
  2578.       goto INSERT_CMDS
  2579.     IF convert( int, substring( @18data, 25, 4 ) ) = 1
  2580.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2581.          substring( @18data, 1, 6 ), substring( @18data, 11, 8 ), @date)
  2582.  
  2583.     IF @19data is null
  2584.       goto INSERT_CMDS
  2585.     IF convert( int, substring( @19data, 25, 4 ) ) = 1
  2586.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2587.          substring( @19data, 1, 6 ), substring( @19data, 11, 8 ), @date)
  2588.  
  2589.     IF @20data is null
  2590.       goto INSERT_CMDS
  2591.     IF convert( int, substring( @20data, 25, 4 ) ) = 1
  2592.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2593.          substring( @20data, 1, 6 ), substring( @20data, 11, 8 ), @date)
  2594.  
  2595.     IF @21data is null
  2596.       goto INSERT_CMDS
  2597.     IF convert( int, substring( @21data, 25, 4 ) ) = 1
  2598.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2599.          substring( @21data, 1, 6 ), substring( @21data, 11, 8 ), @date)
  2600.  
  2601.     IF @22data is null
  2602.       goto INSERT_CMDS
  2603.     IF convert( int, substring( @22data, 25, 4 ) ) = 1
  2604.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2605.          substring( @22data, 1, 6 ), substring( @22data, 11, 8 ), @date)
  2606.  
  2607.     IF @23data is null
  2608.       goto INSERT_CMDS
  2609.     IF convert( int, substring( @23data, 25, 4 ) ) = 1
  2610.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2611.          substring( @23data, 1, 6 ), substring( @23data, 11, 8 ), @date)
  2612.  
  2613.     IF @24data is null
  2614.       goto INSERT_CMDS
  2615.     IF convert( int, substring( @24data, 25, 4 ) ) = 1
  2616.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2617.          substring( @24data, 1, 6 ), substring( @24data, 11, 8 ), @date)
  2618.  
  2619.     IF @25data is null
  2620.       goto INSERT_CMDS
  2621.     IF convert( int, substring( @25data, 25, 4 ) ) = 1
  2622.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2623.          substring( @25data, 1, 6 ), substring( @25data, 11, 8 ), @date)
  2624.  
  2625.     IF @26data is null
  2626.       goto INSERT_CMDS
  2627.     IF convert( int, substring( @26data, 25, 4 ) ) = 1
  2628.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2629.          substring( @26data, 1, 6 ), substring( @26data, 11, 8 ), @date)
  2630.  
  2631. INSERT_CMDS:
  2632.  
  2633.     if datalength( @data ) > 39
  2634.     begin
  2635.         -- Get the originator_id for the first command 
  2636.         select @cmd_data_len = substring( @data, 34, 2 )
  2637.         select @orig_srv_len = substring( @data, 36, 2 )
  2638.         select @orig_db_len = substring( @data, 38, 2 )
  2639.  
  2640.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2641.         begin 
  2642.             set @originator_id = null 
  2643.             select @originator_id = id from MSrepl_originators where
  2644.                 publisher_database_id = @publisher_database_id 
  2645.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @data, 40 + @cmd_data_len, @orig_srv_len )))
  2646.                 and dbname = substring( @data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2647.             if @originator_id is null
  2648.             begin
  2649.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2650.                     (@publisher_database_id, substring( @data, 40 + @cmd_data_len, @orig_srv_len ), substring( @data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2651.                 select @originator_id = @@identity
  2652.             end
  2653.         end
  2654.         else
  2655.             select @originator_id = 0
  2656.  
  2657.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2658.             substring(@data,11,8),
  2659.             substring(@data,29,4), 
  2660.             substring(@data,21,4), 
  2661.             @originator_id, 
  2662.             substring(@data,25,4), 
  2663.             convert(bit,substring(@data,33,1)), 
  2664.             substring(@data,40,@cmd_data_len) )
  2665.     end
  2666.     
  2667.     IF @1data is null
  2668.       return
  2669.     IF datalength( @1data ) > 39
  2670.     begin
  2671.         -- Get the originator_id for the first command 
  2672.         select @cmd_data_len = substring( @1data, 34, 2 )
  2673.         select @orig_srv_len = substring( @1data, 36, 2 )
  2674.         select @orig_db_len = substring( @1data, 38, 2 )
  2675.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2676.         begin 
  2677.             set @originator_id = null 
  2678.             select @originator_id = id from MSrepl_originators where
  2679.                 publisher_database_id = @publisher_database_id 
  2680.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @1data, 40 + @cmd_data_len, @orig_srv_len )))
  2681.                 and dbname = substring( @1data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2682.             if @originator_id is null
  2683.             begin
  2684.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2685.                     (@publisher_database_id, substring( @1data, 40 + @cmd_data_len, @orig_srv_len ), substring( @1data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2686.                 select @originator_id = @@identity
  2687.             end
  2688.         end
  2689.         else
  2690.             select @originator_id = 0
  2691.  
  2692.         -- Now insert into MSrepl_commands
  2693.  
  2694.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2695.             substring(@1data,11,8),
  2696.             substring(@1data,29,4), 
  2697.             substring(@1data,21,4), 
  2698.             @originator_id, 
  2699.             substring(@1data,25,4), 
  2700.             convert(bit,substring(@1data,33,1)), 
  2701.             substring(@1data,40,@cmd_data_len) )
  2702.     end
  2703.  
  2704.     IF @2data is null
  2705.       return
  2706.     IF datalength( @2data ) > 39
  2707.     begin
  2708.         -- Get the originator_id for the first command 
  2709.         select @cmd_data_len = substring( @2data, 34, 2 )
  2710.         select @orig_srv_len = substring( @2data, 36, 2 )
  2711.         select @orig_db_len = substring( @2data, 38, 2 )
  2712.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2713.         begin 
  2714.             set @originator_id = null 
  2715.             select @originator_id = id from MSrepl_originators where
  2716.                 publisher_database_id = @publisher_database_id 
  2717.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @2data, 40 + @cmd_data_len, @orig_srv_len )))
  2718.                 and dbname = substring( @2data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2719.             if @originator_id is null
  2720.             begin
  2721.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2722.                     (@publisher_database_id, substring( @2data, 40 + @cmd_data_len, @orig_srv_len ), substring( @2data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2723.                 select @originator_id = @@identity
  2724.             end
  2725.         end
  2726.         else
  2727.             select @originator_id = 0
  2728.  
  2729.         -- Now insert into MSrepl_commands
  2730.  
  2731.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2732.             substring(@2data,11 ,8),
  2733.             substring(@2data,29 ,4), 
  2734.             substring(@2data,21 ,4), 
  2735.             @originator_id, 
  2736.             substring(@2data,25 ,4), 
  2737.             convert(bit,substring(@2data,33 ,1)), 
  2738.             substring(@2data,40,@cmd_data_len) )
  2739.     end
  2740.  
  2741.     IF @3data is null
  2742.       return
  2743.     IF datalength( @3data ) > 39
  2744.     begin
  2745.         -- Get the originator_id for the first command 
  2746.         select @cmd_data_len = substring( @3data, 34, 2 )
  2747.         select @orig_srv_len = substring( @3data, 36, 2 )
  2748.         select @orig_db_len = substring( @3data, 38, 2 )
  2749.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2750.         begin 
  2751.             set @originator_id = null 
  2752.             select @originator_id = id from MSrepl_originators where
  2753.                 publisher_database_id = @publisher_database_id 
  2754.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @3data, 40 + @cmd_data_len, @orig_srv_len )))
  2755.                 and dbname = substring( @3data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2756.             if @originator_id is null
  2757.             begin
  2758.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2759.                     (@publisher_database_id, substring( @3data, 40 + @cmd_data_len, @orig_srv_len ), substring( @3data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2760.                 select @originator_id = @@identity
  2761.             end
  2762.         end
  2763.         else
  2764.             select @originator_id = 0
  2765.  
  2766.         -- Now insert into MSrepl_commands
  2767.  
  2768.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2769.             substring(@3data,11 ,8),
  2770.             substring(@3data,29 ,4), 
  2771.             substring(@3data,21 ,4), 
  2772.             @originator_id, 
  2773.             substring(@3data,25 ,4), 
  2774.             convert(bit,substring(@3data,33 ,1)), 
  2775.             substring(@3data,40,@cmd_data_len) )
  2776.     end
  2777.  
  2778.     IF @4data is null
  2779.       return
  2780.     IF datalength( @4data ) > 39
  2781.     begin
  2782.         -- Get the originator_id for the first command 
  2783.         select @cmd_data_len = substring( @4data, 34, 2 )
  2784.         select @orig_srv_len = substring( @4data, 36, 2 )
  2785.         select @orig_db_len = substring( @4data, 38, 2 )
  2786.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2787.         begin 
  2788.             set @originator_id = null 
  2789.             select @originator_id = id from MSrepl_originators where
  2790.                 publisher_database_id = @publisher_database_id 
  2791.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @4data, 40 + @cmd_data_len, @orig_srv_len )))
  2792.                 and dbname = substring( @4data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2793.             if @originator_id is null
  2794.             begin
  2795.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2796.                     (@publisher_database_id, substring( @4data, 40 + @cmd_data_len, @orig_srv_len ), substring( @4data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2797.                 select @originator_id = @@identity
  2798.             end
  2799.         end
  2800.         else
  2801.             select @originator_id = 0
  2802.  
  2803.         -- Now insert into MSrepl_commands
  2804.  
  2805.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2806.             substring(@4data,11 ,8),
  2807.             substring(@4data,29 ,4), 
  2808.             substring(@4data,21 ,4), 
  2809.             @originator_id, 
  2810.             substring(@4data,25 ,4), 
  2811.             convert(bit,substring(@4data,33 ,1)), 
  2812.             substring(@4data,40,@cmd_data_len) )
  2813.     end
  2814.  
  2815.     IF @5data is null
  2816.       return
  2817.     IF datalength( @5data ) > 39
  2818.     begin
  2819.         -- Get the originator_id for the first command 
  2820.         select @cmd_data_len = substring( @5data, 34, 2 )
  2821.         select @orig_srv_len = substring( @5data, 36, 2 )
  2822.         select @orig_db_len = substring( @5data, 38, 2 )
  2823.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2824.         begin 
  2825.             set @originator_id = null 
  2826.             select @originator_id = id from MSrepl_originators where
  2827.                 publisher_database_id = @publisher_database_id 
  2828.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @5data, 40 + @cmd_data_len, @orig_srv_len )))
  2829.                 and dbname = substring( @5data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2830.             if @originator_id is null
  2831.             begin
  2832.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2833.                     (@publisher_database_id, substring( @5data, 40 + @cmd_data_len, @orig_srv_len ), substring( @5data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2834.                 select @originator_id = @@identity
  2835.             end
  2836.         end
  2837.         else
  2838.             select @originator_id = 0
  2839.  
  2840.         -- Now insert into MSrepl_commands
  2841.  
  2842.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2843.             substring(@5data,11 ,8),
  2844.             substring(@5data,29 ,4), 
  2845.             substring(@5data,21 ,4), 
  2846.             @originator_id, 
  2847.             substring(@5data,25 ,4), 
  2848.             convert(bit,substring(@5data,33 ,1)), 
  2849.             substring(@5data,40,@cmd_data_len) )
  2850.     end
  2851.  
  2852.     IF @6data is null
  2853.       return
  2854.     IF datalength( @6data ) > 39
  2855.     begin
  2856.         -- Get the originator_id for the first command 
  2857.         select @cmd_data_len = substring( @6data, 34, 2 )
  2858.         select @orig_srv_len = substring( @6data, 36, 2 )
  2859.         select @orig_db_len = substring( @6data, 38, 2 )
  2860.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2861.         begin 
  2862.             set @originator_id = null 
  2863.             select @originator_id = id from MSrepl_originators where
  2864.                 publisher_database_id = @publisher_database_id 
  2865.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @6data, 40 + @cmd_data_len, @orig_srv_len )))
  2866.                 and dbname = substring( @6data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2867.             if @originator_id is null
  2868.             begin
  2869.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2870.                     (@publisher_database_id, substring( @6data, 40 + @cmd_data_len, @orig_srv_len ), substring( @6data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2871.                 select @originator_id = @@identity
  2872.             end
  2873.         end
  2874.         else
  2875.             select @originator_id = 0
  2876.  
  2877.         -- Now insert into MSrepl_commands
  2878.  
  2879.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2880.             substring(@6data,11 ,8),
  2881.             substring(@6data,29 ,4), 
  2882.             substring(@6data,21 ,4), 
  2883.             @originator_id, 
  2884.             substring(@6data,25 ,4), 
  2885.             convert(bit,substring(@6data,33 ,1)), 
  2886.             substring(@6data,40,@cmd_data_len) )
  2887.     end
  2888.  
  2889.     IF @7data is null
  2890.       return
  2891.     IF datalength( @7data ) > 39
  2892.     begin
  2893.         -- Get the originator_id for the first command 
  2894.         select @cmd_data_len = substring( @7data, 34, 2 )
  2895.         select @orig_srv_len = substring( @7data, 36, 2 )
  2896.         select @orig_db_len = substring( @7data, 38, 2 )
  2897.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2898.         begin 
  2899.             set @originator_id = null 
  2900.             select @originator_id = id from MSrepl_originators where
  2901.                 publisher_database_id = @publisher_database_id 
  2902.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @7data, 40 + @cmd_data_len, @orig_srv_len )))
  2903.                 and dbname = substring( @7data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2904.             if @originator_id is null
  2905.             begin
  2906.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2907.                     (@publisher_database_id, substring( @7data, 40 + @cmd_data_len, @orig_srv_len ), substring( @7data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2908.                 select @originator_id = @@identity
  2909.             end
  2910.         end
  2911.         else
  2912.             select @originator_id = 0
  2913.  
  2914.         -- Now insert into MSrepl_commands
  2915.  
  2916.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2917.             substring(@7data,11 ,8),
  2918.             substring(@7data,29 ,4), 
  2919.             substring(@7data,21 ,4), 
  2920.             @originator_id, 
  2921.             substring(@7data,25 ,4), 
  2922.             convert(bit,substring(@7data,33 ,1)), 
  2923.             substring(@7data,40,@cmd_data_len) )
  2924.     end
  2925.  
  2926.     IF @8data is null
  2927.       return
  2928.     IF datalength( @8data ) > 39
  2929.     begin
  2930.         -- Get the originator_id for the first command 
  2931.         select @cmd_data_len = substring( @8data, 34, 2 )
  2932.         select @orig_srv_len = substring( @8data, 36, 2 )
  2933.         select @orig_db_len = substring( @8data, 38, 2 )
  2934.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2935.         begin 
  2936.             set @originator_id = null 
  2937.             select @originator_id = id from MSrepl_originators where
  2938.                 publisher_database_id = @publisher_database_id 
  2939.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @8data, 40 + @cmd_data_len, @orig_srv_len )))
  2940.                 and dbname = substring( @8data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2941.             if @originator_id is null
  2942.             begin
  2943.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2944.                     (@publisher_database_id, substring( @8data, 40 + @cmd_data_len, @orig_srv_len ), substring( @8data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2945.                 select @originator_id = @@identity
  2946.             end
  2947.         end
  2948.         else
  2949.             select @originator_id = 0
  2950.  
  2951.         -- Now insert into MSrepl_commands
  2952.  
  2953.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2954.             substring(@8data,11 ,8),
  2955.             substring(@8data,29 ,4), 
  2956.             substring(@8data,21 ,4), 
  2957.             @originator_id, 
  2958.             substring(@8data,25 ,4), 
  2959.             convert(bit,substring(@8data,33 ,1)), 
  2960.             substring(@8data,40,@cmd_data_len) )
  2961.     end
  2962.  
  2963.     IF @9data is null
  2964.       return
  2965.     IF datalength( @9data ) > 39
  2966.     begin
  2967.         -- Get the originator_id for the first command 
  2968.         select @cmd_data_len = substring( @9data, 34, 2 )
  2969.         select @orig_srv_len = substring( @9data, 36, 2 )
  2970.         select @orig_db_len = substring( @9data, 38, 2 )
  2971.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2972.         begin 
  2973.             set @originator_id = null 
  2974.             select @originator_id = id from MSrepl_originators where
  2975.                 publisher_database_id = @publisher_database_id 
  2976.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @9data, 40 + @cmd_data_len, @orig_srv_len )))
  2977.                 and dbname = substring( @9data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2978.             if @originator_id is null
  2979.             begin
  2980.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2981.                     (@publisher_database_id, substring( @9data, 40 + @cmd_data_len, @orig_srv_len ), substring( @9data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2982.                 select @originator_id = @@identity
  2983.             end
  2984.         end
  2985.         else
  2986.             select @originator_id = 0
  2987.  
  2988.         -- Now insert into MSrepl_commands
  2989.  
  2990.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2991.             substring(@9data,11 ,8),
  2992.             substring(@9data,29 ,4), 
  2993.             substring(@9data,21 ,4), 
  2994.             @originator_id, 
  2995.             substring(@9data,25 ,4), 
  2996.             convert(bit,substring(@9data,33 ,1)), 
  2997.             substring(@9data,40,@cmd_data_len) )
  2998.     end
  2999.  
  3000.     IF @10data is null
  3001.       return
  3002.     IF datalength( @10data ) > 39
  3003.     begin
  3004.         -- Get the originator_id for the first command 
  3005.         select @cmd_data_len = substring( @10data, 34, 2 )
  3006.         select @orig_srv_len = substring( @10data, 36, 2 )
  3007.         select @orig_db_len = substring( @10data, 38, 2 )
  3008.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3009.         begin 
  3010.             set @originator_id = null 
  3011.             select @originator_id = id from MSrepl_originators where
  3012.                 publisher_database_id = @publisher_database_id 
  3013.                 and UPPER(srvname) = upper(convert(sysname, substring( @10data, 40 + @cmd_data_len, @orig_srv_len )))
  3014.                 and dbname = substring( @10data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3015.             if @originator_id is null
  3016.             begin
  3017.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3018.                     (@publisher_database_id, substring( @10data, 40 + @cmd_data_len, @orig_srv_len ), substring( @10data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3019.                 select @originator_id = @@identity
  3020.             end
  3021.         end
  3022.         else
  3023.             select @originator_id = 0
  3024.  
  3025.         -- Now insert into MSrepl_commands
  3026.  
  3027.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3028.             substring(@10data,11 ,8),
  3029.             substring(@10data,29 ,4), 
  3030.             substring(@10data,21 ,4), 
  3031.             @originator_id, 
  3032.             substring(@10data,25 ,4), 
  3033.             convert(bit,substring(@10data,33 ,1)), 
  3034.             substring(@10data,40,@cmd_data_len) )
  3035.     end
  3036.  
  3037.     IF @11data is null
  3038.       return
  3039.     IF datalength( @11data ) > 39
  3040.     begin
  3041.         -- Get the originator_id for the first command 
  3042.         select @cmd_data_len = substring( @11data, 34, 2 )
  3043.         select @orig_srv_len = substring( @11data, 36, 2 )
  3044.         select @orig_db_len = substring( @11data, 38, 2 )
  3045.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3046.         begin 
  3047.             set @originator_id = null 
  3048.             select @originator_id = id from MSrepl_originators where
  3049.                 publisher_database_id = @publisher_database_id 
  3050.                 and UPPER(srvname) = upper(convert(sysname, substring( @11data, 40 + @cmd_data_len, @orig_srv_len )))
  3051.                 and dbname = substring( @11data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3052.             if @originator_id is null
  3053.             begin
  3054.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3055.                     (@publisher_database_id, substring( @11data, 40 + @cmd_data_len, @orig_srv_len ), substring( @11data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3056.                 select @originator_id = @@identity
  3057.             end
  3058.         end
  3059.         else
  3060.             select @originator_id = 0
  3061.  
  3062.         -- Now insert into MSrepl_commands
  3063.  
  3064.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3065.             substring(@11data,11 ,8),
  3066.             substring(@11data,29 ,4), 
  3067.             substring(@11data,21 ,4), 
  3068.             @originator_id, 
  3069.             substring(@11data,25 ,4), 
  3070.             convert(bit,substring(@11data,33 ,1)), 
  3071.             substring(@11data,40,@cmd_data_len) )
  3072.     end
  3073.  
  3074.     IF @12data is null
  3075.       return
  3076.     IF datalength( @12data ) > 39
  3077.     begin
  3078.         -- Get the originator_id for the first command 
  3079.         select @cmd_data_len = substring( @12data, 34, 2 )
  3080.         select @orig_srv_len = substring( @12data, 36, 2 )
  3081.         select @orig_db_len = substring( @12data, 38, 2 )
  3082.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3083.         begin 
  3084.             set @originator_id = null 
  3085.             select @originator_id = id from MSrepl_originators where
  3086.                 publisher_database_id = @publisher_database_id 
  3087.                 and UPPER(srvname) = upper(convert(sysname, substring( @12data, 40 + @cmd_data_len, @orig_srv_len )))
  3088.                 and dbname = substring( @12data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3089.             if @originator_id is null
  3090.             begin
  3091.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3092.                     (@publisher_database_id, substring( @12data, 40 + @cmd_data_len, @orig_srv_len ), substring( @12data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3093.                 select @originator_id = @@identity
  3094.             end
  3095.         end
  3096.         else
  3097.             select @originator_id = 0
  3098.  
  3099.         -- Now insert into MSrepl_commands
  3100.  
  3101.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3102.             substring(@12data,11 ,8),
  3103.             substring(@12data,29 ,4), 
  3104.             substring(@12data,21 ,4), 
  3105.             @originator_id, 
  3106.             substring(@12data,25 ,4), 
  3107.             convert(bit,substring(@12data,33 ,1)), 
  3108.             substring(@12data,40,@cmd_data_len) )
  3109.     end
  3110.  
  3111.  
  3112.     IF @13data is null
  3113.       return
  3114.     IF datalength( @13data ) > 39
  3115.     begin
  3116.         -- Get the originator_id for the first command 
  3117.         select @cmd_data_len = substring( @13data, 34, 2 )
  3118.         select @orig_srv_len = substring( @13data, 36, 2 )
  3119.         select @orig_db_len = substring( @13data, 38, 2 )
  3120.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3121.         begin 
  3122.             set @originator_id = null 
  3123.             select @originator_id = id from MSrepl_originators where
  3124.                 publisher_database_id = @publisher_database_id 
  3125.                 and UPPER(srvname) = upper(convert(sysname, substring( @13data, 40 + @cmd_data_len, @orig_srv_len )))
  3126.                 and dbname = substring( @13data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3127.             if @originator_id is null
  3128.             begin
  3129.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3130.                     (@publisher_database_id, substring( @13data, 40 + @cmd_data_len, @orig_srv_len ), substring( @13data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3131.                 select @originator_id = @@identity
  3132.             end
  3133.         end
  3134.         else
  3135.             select @originator_id = 0
  3136.  
  3137.         -- Now insert into MSrepl_commands
  3138.  
  3139.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3140.             substring(@13data,11 ,8),
  3141.             substring(@13data,29 ,4), 
  3142.             substring(@13data,21 ,4), 
  3143.             @originator_id, 
  3144.             substring(@13data,25 ,4), 
  3145.             convert(bit,substring(@13data,33 ,1)), 
  3146.             substring(@13data,40,@cmd_data_len) )
  3147.     end
  3148.  
  3149.     IF @14data is null
  3150.       return
  3151.     IF datalength( @14data ) > 39
  3152.     begin
  3153.         -- Get the originator_id for the first command 
  3154.         select @cmd_data_len = substring( @14data, 34, 2 )
  3155.         select @orig_srv_len = substring( @14data, 36, 2 )
  3156.         select @orig_db_len = substring( @14data, 38, 2 )
  3157.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3158.         begin 
  3159.             set @originator_id = null 
  3160.             select @originator_id = id from MSrepl_originators where
  3161.                 publisher_database_id = @publisher_database_id 
  3162.                 and UPPER(srvname) = upper(convert(sysname, substring( @14data, 40 + @cmd_data_len, @orig_srv_len )))
  3163.                 and dbname = substring( @14data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3164.             if @originator_id is null
  3165.             begin
  3166.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3167.                     (@publisher_database_id, substring( @14data, 40 + @cmd_data_len, @orig_srv_len ), substring( @14data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3168.                 select @originator_id = @@identity
  3169.             end
  3170.         end
  3171.         else
  3172.             select @originator_id = 0
  3173.  
  3174.         -- Now insert into MSrepl_commands
  3175.  
  3176.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3177.             substring(@14data,11 ,8),
  3178.             substring(@14data,29 ,4), 
  3179.             substring(@14data,21 ,4), 
  3180.             @originator_id, 
  3181.             substring(@14data,25 ,4), 
  3182.             convert(bit,substring(@14data,33 ,1)), 
  3183.             substring(@14data,40,@cmd_data_len) )
  3184.     end
  3185.  
  3186.  
  3187.     IF @15data is null
  3188.       return
  3189.     IF datalength( @15data ) > 39
  3190.     begin
  3191.         -- Get the originator_id for the first command 
  3192.         select @cmd_data_len = substring( @15data, 34, 2 )
  3193.         select @orig_srv_len = substring( @15data, 36, 2 )
  3194.         select @orig_db_len = substring( @15data, 38, 2 )
  3195.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3196.         begin 
  3197.             set @originator_id = null 
  3198.             select @originator_id = id from MSrepl_originators where
  3199.                 publisher_database_id = @publisher_database_id 
  3200.                 and UPPER(srvname) = upper(convert(sysname, substring( @15data, 40 + @cmd_data_len, @orig_srv_len )))
  3201.                 and dbname = substring( @15data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3202.             if @originator_id is null
  3203.             begin
  3204.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3205.                     (@publisher_database_id, substring( @15data, 40 + @cmd_data_len, @orig_srv_len ), substring( @15data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3206.                 select @originator_id = @@identity
  3207.             end
  3208.         end
  3209.         else
  3210.             select @originator_id = 0
  3211.  
  3212.         -- Now insert into MSrepl_commands
  3213.  
  3214.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3215.             substring(@15data,11 ,8),
  3216.             substring(@15data,29 ,4), 
  3217.             substring(@15data,21 ,4), 
  3218.             @originator_id, 
  3219.             substring(@15data,25 ,4), 
  3220.             convert(bit,substring(@15data,33 ,1)), 
  3221.             substring(@15data,40,@cmd_data_len) )
  3222.     end
  3223.  
  3224.     IF @16data is null
  3225.       return
  3226.     IF datalength( @16data ) > 39
  3227.     begin
  3228.         -- Get the originator_id for the first command 
  3229.         select @cmd_data_len = substring( @16data, 34, 2 )
  3230.         select @orig_srv_len = substring( @16data, 36, 2 )
  3231.         select @orig_db_len = substring( @16data, 38, 2 )
  3232.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3233.         begin 
  3234.             set @originator_id = null 
  3235.             select @originator_id = id from MSrepl_originators where
  3236.                 publisher_database_id = @publisher_database_id 
  3237.                 and UPPER(srvname) = upper(convert(sysname, substring( @16data, 40 + @cmd_data_len, @orig_srv_len )))
  3238.                 and dbname = substring( @16data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3239.             if @originator_id is null
  3240.             begin
  3241.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3242.                     (@publisher_database_id, substring( @16data, 40 + @cmd_data_len, @orig_srv_len ), substring( @16data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3243.                 select @originator_id = @@identity
  3244.             end
  3245.         end
  3246.         else
  3247.             select @originator_id = 0
  3248.  
  3249.         -- Now insert into MSrepl_commands
  3250.  
  3251.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3252.             substring(@16data,11 ,8),
  3253.             substring(@16data,29 ,4), 
  3254.             substring(@16data,21 ,4), 
  3255.             @originator_id, 
  3256.             substring(@16data,25 ,4), 
  3257.             convert(bit,substring(@16data,33 ,1)), 
  3258.             substring(@16data,40,@cmd_data_len) )
  3259.     end
  3260.  
  3261.  
  3262.     IF @17data is null
  3263.       return
  3264.     IF datalength( @17data ) > 39
  3265.     begin
  3266.         -- Get the originator_id for the first command 
  3267.         select @cmd_data_len = substring( @17data, 34, 2 )
  3268.         select @orig_srv_len = substring( @17data, 36, 2 )
  3269.         select @orig_db_len = substring( @17data, 38, 2 )
  3270.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3271.         begin 
  3272.             set @originator_id = null 
  3273.             select @originator_id = id from MSrepl_originators where
  3274.                 publisher_database_id = @publisher_database_id 
  3275.                 and UPPER(srvname) = upper(convert(sysname, substring( @17data, 40 + @cmd_data_len, @orig_srv_len )))
  3276.                 and dbname = substring( @17data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3277.             if @originator_id is null
  3278.             begin
  3279.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3280.                     (@publisher_database_id, substring( @17data, 40 + @cmd_data_len, @orig_srv_len ), substring( @17data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3281.                 select @originator_id = @@identity
  3282.             end
  3283.         end
  3284.         else
  3285.             select @originator_id = 0
  3286.  
  3287.         -- Now insert into MSrepl_commands
  3288.  
  3289.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3290.             substring(@17data,11 ,8),
  3291.             substring(@17data,29 ,4), 
  3292.             substring(@17data,21 ,4), 
  3293.             @originator_id, 
  3294.             substring(@17data,25 ,4), 
  3295.             convert(bit,substring(@17data,33 ,1)), 
  3296.             substring(@17data,40,@cmd_data_len) )
  3297.     end
  3298.  
  3299.  
  3300.     IF @18data is null
  3301.       return
  3302.     IF datalength( @18data ) > 39
  3303.     begin
  3304.         -- Get the originator_id for the first command 
  3305.         select @cmd_data_len = substring( @18data, 34, 2 )
  3306.         select @orig_srv_len = substring( @18data, 36, 2 )
  3307.         select @orig_db_len = substring( @18data, 38, 2 )
  3308.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3309.         begin 
  3310.             set @originator_id = null 
  3311.             select @originator_id = id from MSrepl_originators where
  3312.                 publisher_database_id = @publisher_database_id 
  3313.                 and UPPER(srvname) = upper(convert(sysname, substring( @18data, 40 + @cmd_data_len, @orig_srv_len )))
  3314.                 and dbname = substring( @18data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3315.             if @originator_id is null
  3316.             begin
  3317.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3318.                     (@publisher_database_id, substring( @18data, 40 + @cmd_data_len, @orig_srv_len ), substring( @18data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3319.                 select @originator_id = @@identity
  3320.             end
  3321.         end
  3322.         else
  3323.             select @originator_id = 0
  3324.  
  3325.         -- Now insert into MSrepl_commands
  3326.  
  3327.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3328.             substring(@18data,11 ,8),
  3329.             substring(@18data,29 ,4), 
  3330.             substring(@18data,21 ,4), 
  3331.             @originator_id, 
  3332.             substring(@18data,25 ,4), 
  3333.             convert(bit,substring(@18data,33 ,1)), 
  3334.             substring(@18data,40,@cmd_data_len) )
  3335.     end
  3336.  
  3337.  
  3338.     IF @19data is null
  3339.       return
  3340.     IF datalength( @19data ) > 39
  3341.     begin
  3342.         -- Get the originator_id for the first command 
  3343.         select @cmd_data_len = substring( @19data, 34, 2 )
  3344.         select @orig_srv_len = substring( @19data, 36, 2 )
  3345.         select @orig_db_len = substring( @19data, 38, 2 )
  3346.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3347.         begin 
  3348.             set @originator_id = null 
  3349.             select @originator_id = id from MSrepl_originators where
  3350.                 publisher_database_id = @publisher_database_id 
  3351.                 and UPPER(srvname) = upper(convert(sysname, substring( @19data, 40 + @cmd_data_len, @orig_srv_len )))
  3352.                 and dbname = substring( @19data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3353.             if @originator_id is null
  3354.             begin
  3355.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3356.                     (@publisher_database_id, substring( @19data, 40 + @cmd_data_len, @orig_srv_len ), substring( @19data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3357.                 select @originator_id = @@identity
  3358.             end
  3359.         end
  3360.         else
  3361.             select @originator_id = 0
  3362.  
  3363.         -- Now insert into MSrepl_commands
  3364.  
  3365.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3366.             substring(@19data,11 ,8),
  3367.             substring(@19data,29 ,4), 
  3368.             substring(@19data,21 ,4), 
  3369.             @originator_id, 
  3370.             substring(@19data,25 ,4), 
  3371.             convert(bit,substring(@19data,33 ,1)), 
  3372.             substring(@19data,40,@cmd_data_len) )
  3373.     end
  3374.  
  3375.  
  3376.     IF @20data is null
  3377.       return
  3378.     IF datalength( @20data ) > 39
  3379.     begin
  3380.         -- Get the originator_id for the first command 
  3381.         select @cmd_data_len = substring( @20data, 34, 2 )
  3382.         select @orig_srv_len = substring( @20data, 36, 2 )
  3383.         select @orig_db_len = substring( @20data, 38, 2 )
  3384.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3385.         begin 
  3386.             set @originator_id = null 
  3387.             select @originator_id = id from MSrepl_originators where
  3388.                 publisher_database_id = @publisher_database_id 
  3389.                 and UPPER(srvname) = upper(convert(sysname, substring( @20data, 40 + @cmd_data_len, @orig_srv_len )))
  3390.                 and dbname = substring( @20data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3391.             if @originator_id is null
  3392.             begin
  3393.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3394.                     (@publisher_database_id, substring( @20data, 40 + @cmd_data_len, @orig_srv_len ), substring( @20data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3395.                 select @originator_id = @@identity
  3396.             end
  3397.         end
  3398.         else
  3399.             select @originator_id = 0
  3400.  
  3401.         -- Now insert into MSrepl_commands
  3402.  
  3403.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3404.             substring(@20data,11 ,8),
  3405.             substring(@20data,29 ,4), 
  3406.             substring(@20data,21 ,4), 
  3407.             @originator_id, 
  3408.             substring(@20data,25 ,4), 
  3409.             convert(bit,substring(@20data,33 ,1)), 
  3410.             substring(@20data,40,@cmd_data_len) )
  3411.     end
  3412.  
  3413.     IF @21data is null
  3414.       return
  3415.     IF datalength( @21data ) > 39
  3416.     begin
  3417.         -- Get the originator_id for the first command 
  3418.         select @cmd_data_len = substring( @21data, 34, 2 )
  3419.         select @orig_srv_len = substring( @21data, 36, 2 )
  3420.         select @orig_db_len = substring( @21data, 38, 2 )
  3421.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3422.         begin 
  3423.             set @originator_id = null 
  3424.             select @originator_id = id from MSrepl_originators where
  3425.                 publisher_database_id = @publisher_database_id 
  3426.                 and UPPER(srvname) = upper(convert(sysname, substring( @21data, 40 + @cmd_data_len, @orig_srv_len )))
  3427.                 and dbname = substring( @21data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3428.             if @originator_id is null
  3429.             begin
  3430.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3431.                     (@publisher_database_id, substring( @21data, 40 + @cmd_data_len, @orig_srv_len ), substring( @21data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3432.                 select @originator_id = @@identity
  3433.             end
  3434.         end
  3435.         else
  3436.             select @originator_id = 0
  3437.  
  3438.         -- Now insert into MSrepl_commands
  3439.  
  3440.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3441.             substring(@21data,11 ,8),
  3442.             substring(@21data,29 ,4), 
  3443.             substring(@21data,21 ,4), 
  3444.             @originator_id, 
  3445.             substring(@21data,25 ,4), 
  3446.             convert(bit,substring(@21data,33 ,1)), 
  3447.             substring(@21data,40,@cmd_data_len) )
  3448.     end
  3449.  
  3450.     IF @22data is null
  3451.       return
  3452.     IF datalength( @22data ) > 39
  3453.     begin
  3454.         -- Get the originator_id for the first command 
  3455.         select @cmd_data_len = substring( @22data, 34, 2 )
  3456.         select @orig_srv_len = substring( @22data, 36, 2 )
  3457.         select @orig_db_len = substring( @22data, 38, 2 )
  3458.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3459.         begin 
  3460.             set @originator_id = null 
  3461.             select @originator_id = id from MSrepl_originators where
  3462.                 publisher_database_id = @publisher_database_id 
  3463.                 and UPPER(srvname) = upper(convert(sysname, substring( @22data, 40 + @cmd_data_len, @orig_srv_len )))
  3464.                 and dbname = substring( @22data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3465.             if @originator_id is null
  3466.             begin
  3467.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3468.                     (@publisher_database_id, substring( @22data, 40 + @cmd_data_len, @orig_srv_len ), substring( @22data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3469.                 select @originator_id = @@identity
  3470.             end
  3471.         end
  3472.         else
  3473.             select @originator_id = 0
  3474.  
  3475.         -- Now insert into MSrepl_commands
  3476.  
  3477.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3478.             substring(@22data,11 ,8),
  3479.             substring(@22data,29 ,4), 
  3480.             substring(@22data,21 ,4), 
  3481.             @originator_id, 
  3482.             substring(@22data,25 ,4), 
  3483.             convert(bit,substring(@22data,33 ,1)), 
  3484.             substring(@22data,40,@cmd_data_len) )
  3485.     end
  3486.  
  3487.     IF @23data is null
  3488.       return
  3489.     IF datalength( @23data ) > 39
  3490.     begin
  3491.         -- Get the originator_id for the first command 
  3492.         select @cmd_data_len = substring( @23data, 34, 2 )
  3493.         select @orig_srv_len = substring( @23data, 36, 2 )
  3494.         select @orig_db_len = substring( @23data, 38, 2 )
  3495.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3496.         begin 
  3497.             set @originator_id = null 
  3498.             select @originator_id = id from MSrepl_originators where
  3499.                 publisher_database_id = @publisher_database_id 
  3500.                 and UPPER(srvname) = upper(convert(sysname, substring( @23data, 40 + @cmd_data_len, @orig_srv_len )))
  3501.                 and dbname = substring( @23data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3502.             if @originator_id is null
  3503.             begin
  3504.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3505.                     (@publisher_database_id, substring( @23data, 40 + @cmd_data_len, @orig_srv_len ), substring( @23data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3506.                 select @originator_id = @@identity
  3507.             end
  3508.         end
  3509.         else
  3510.             select @originator_id = 0
  3511.  
  3512.         -- Now insert into MSrepl_commands
  3513.  
  3514.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3515.             substring(@23data,11 ,8),
  3516.             substring(@23data,29 ,4), 
  3517.             substring(@23data,21 ,4), 
  3518.             @originator_id, 
  3519.             substring(@23data,25 ,4), 
  3520.             convert(bit,substring(@23data,33 ,1)), 
  3521.             substring(@23data,40,@cmd_data_len) )
  3522.     end
  3523.  
  3524.     IF @24data is null
  3525.       return
  3526.     IF datalength( @24data ) > 39
  3527.     begin
  3528.         -- Get the originator_id for the first command 
  3529.         select @cmd_data_len = substring( @24data, 34, 2 )
  3530.         select @orig_srv_len = substring( @24data, 36, 2 )
  3531.         select @orig_db_len = substring( @24data, 38, 2 )
  3532.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3533.         begin 
  3534.             set @originator_id = null 
  3535.             select @originator_id = id from MSrepl_originators where
  3536.                 publisher_database_id = @publisher_database_id 
  3537.                 and UPPER(srvname) = upper(convert(sysname, substring( @24data, 40 + @cmd_data_len, @orig_srv_len )))
  3538.                 and dbname = substring( @24data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3539.             if @originator_id is null
  3540.             begin
  3541.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3542.                     (@publisher_database_id, substring( @24data, 40 + @cmd_data_len, @orig_srv_len ), substring( @24data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3543.                 select @originator_id = @@identity
  3544.             end
  3545.         end
  3546.         else
  3547.             select @originator_id = 0
  3548.  
  3549.         -- Now insert into MSrepl_commands
  3550.  
  3551.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3552.             substring(@24data,11 ,8),
  3553.             substring(@24data,29 ,4), 
  3554.             substring(@24data,21 ,4), 
  3555.             @originator_id, 
  3556.             substring(@24data,25 ,4), 
  3557.             convert(bit,substring(@24data,33 ,1)), 
  3558.             substring(@24data,40,@cmd_data_len) )
  3559.     end
  3560.  
  3561.  
  3562.     IF @25data is null
  3563.       return
  3564.     IF datalength( @25data ) > 39
  3565.     begin
  3566.         -- Get the originator_id for the first command 
  3567.         select @cmd_data_len = substring( @25data, 34, 2 )
  3568.         select @orig_srv_len = substring( @25data, 36, 2 )
  3569.         select @orig_db_len = substring( @25data, 38, 2 )
  3570.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3571.         begin 
  3572.             set @originator_id = null 
  3573.             select @originator_id = id from MSrepl_originators where
  3574.                 publisher_database_id = @publisher_database_id 
  3575.                 and UPPER(srvname) = upper(convert(sysname, substring( @25data, 40 + @cmd_data_len, @orig_srv_len )))
  3576.                 and dbname = substring( @25data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3577.             if @originator_id is null
  3578.             begin
  3579.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3580.                     (@publisher_database_id, substring( @25data, 40 + @cmd_data_len, @orig_srv_len ), substring( @25data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3581.                 select @originator_id = @@identity
  3582.             end
  3583.         end
  3584.         else
  3585.             select @originator_id = 0
  3586.  
  3587.         -- Now insert into MSrepl_commands
  3588.  
  3589.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3590.             substring(@25data,11 ,8),
  3591.             substring(@25data,29 ,4), 
  3592.             substring(@25data,21 ,4), 
  3593.             @originator_id, 
  3594.             substring(@25data,25 ,4), 
  3595.             convert(bit,substring(@25data,33 ,1)), 
  3596.             substring(@25data,40,@cmd_data_len) )
  3597.     end
  3598.  
  3599.  
  3600.     IF @26data is null
  3601.       return
  3602.     IF datalength( @26data ) > 39
  3603.     begin
  3604.         -- Get the originator_id for the first command 
  3605.         select @cmd_data_len = substring( @26data, 34, 2 )
  3606.         select @orig_srv_len = substring( @26data, 36, 2 )
  3607.         select @orig_db_len = substring( @26data, 38, 2 )
  3608.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3609.         begin 
  3610.             set @originator_id = null 
  3611.             select @originator_id = id from MSrepl_originators where
  3612.                 publisher_database_id = @publisher_database_id 
  3613.                 and UPPER(srvname) = upper(convert(sysname, substring( @26data, 40 + @cmd_data_len, @orig_srv_len )))
  3614.                 and dbname = substring( @26data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3615.             if @originator_id is null
  3616.             begin
  3617.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3618.                     (@publisher_database_id, substring( @26data, 40 + @cmd_data_len, @orig_srv_len ), substring( @26data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3619.                 select @originator_id = @@identity
  3620.             end
  3621.         end
  3622.         else
  3623.             select @originator_id = 0
  3624.  
  3625.         -- Now insert into MSrepl_commands
  3626.  
  3627.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3628.             substring(@26data,11 ,8),
  3629.             substring(@26data,29 ,4), 
  3630.             substring(@26data,21 ,4), 
  3631.             @originator_id, 
  3632.             substring(@26data,25 ,4), 
  3633.             convert(bit,substring(@26data,33 ,1)), 
  3634.             substring(@26data,40,@cmd_data_len) )
  3635.     end
  3636.  
  3637.  
  3638.     IF @@ERROR <> 0
  3639.       return (1)
  3640. GO
  3641. raiserror(15339,-1,-1,'sp_MSadd_repl_commands27hp')
  3642. GO
  3643. CREATE PROCEDURE sp_MSadd_repl_commands27hp
  3644. @publisher_id smallint,
  3645. @publisher_db sysname,
  3646. @data varbinary( 1575 ),
  3647. @1data varbinary(1575) = NULL,
  3648. @2data varbinary(1575) = NULL,
  3649. @3data varbinary(1575) = NULL,
  3650. @4data varbinary(1575) = NULL,
  3651. @5data varbinary(1575) = NULL,
  3652. @6data varbinary(1575) = NULL,
  3653. @7data varbinary(1575) = NULL,
  3654. @8data varbinary(1575) = NULL,
  3655. @9data varbinary(1575) = NULL,
  3656. @10data varbinary(1575) = NULL,
  3657. @11data varbinary(1575) = NULL,
  3658. @12data varbinary(1575) = NULL,
  3659. @13data varbinary(1575) = NULL,
  3660. @14data varbinary(1575) = NULL,
  3661. @15data varbinary(1575) = NULL,
  3662. @16data varbinary(1575) = NULL,
  3663. @17data varbinary(1575) = NULL,
  3664. @18data varbinary(1575) = NULL,
  3665. @19data varbinary(1575) = NULL,
  3666. @20data varbinary(1575) = NULL,
  3667. @21data varbinary(1575) = NULL,
  3668. @22data varbinary(1575) = NULL,
  3669. @23data varbinary(1575) = NULL,
  3670. @24data varbinary(1575) = NULL,
  3671. @25data varbinary(1575) = NULL,
  3672. @26data varbinary(1575) = NULL
  3673. AS
  3674.  
  3675.     SET NOCOUNT ON
  3676.  
  3677.     DECLARE @xact_id    varbinary(10)
  3678.     DECLARE @xact_seqno varbinary(10)
  3679.     DECLARE @artid      int
  3680.     DECLARE @command_id int
  3681.     DECLARE @cmd_type   int
  3682.     DECLARE @partial_command bit
  3683.     DECLARE @command    varbinary(1024)
  3684.  
  3685.     DECLARE @max_offset  binary(4)
  3686.     DECLARE @seqno  varbinary(16)
  3687.     DECLARE @1seqno  varbinary(16)
  3688.     DECLARE @2seqno  varbinary(16)
  3689.     DECLARE @3seqno  varbinary(16)
  3690.     DECLARE @4seqno  varbinary(16)
  3691.     DECLARE @5seqno  varbinary(16)
  3692.     DECLARE @6seqno  varbinary(16)
  3693.     DECLARE @7seqno  varbinary(16)
  3694.     DECLARE @8seqno  varbinary(16)
  3695.     DECLARE @9seqno  varbinary(16)
  3696.     DECLARE @10seqno  varbinary(16)
  3697.     DECLARE @11seqno  varbinary(16)
  3698.     DECLARE @12seqno  varbinary(16)
  3699.     DECLARE @13seqno  varbinary(16)
  3700.     DECLARE @14seqno  varbinary(16)
  3701.     DECLARE @15seqno  varbinary(16)
  3702.     DECLARE @16seqno  varbinary(16)
  3703.     DECLARE @17seqno  varbinary(16)
  3704.     DECLARE @18seqno  varbinary(16)
  3705.     DECLARE @19seqno  varbinary(16)
  3706.     DECLARE @20seqno  varbinary(16)
  3707.     DECLARE @21seqno  varbinary(16)
  3708.     DECLARE @22seqno  varbinary(16)
  3709.     DECLARE @23seqno  varbinary(16)
  3710.     DECLARE @24seqno  varbinary(16)
  3711.     DECLARE @25seqno  varbinary(16)
  3712.     DECLARE @26seqno  varbinary(16)
  3713.     DECLARE @max_seqno  varbinary(16)
  3714.  
  3715.     DECLARE @originator sysname
  3716.     DECLARE @originator_db sysname
  3717.  
  3718.     DECLARE @publisher_database_id int
  3719.     DECLARE @date datetime
  3720.     declare @originator_id int
  3721.  
  3722.     DECLARE @cmd_data_len  smallint
  3723.     DECLARE @orig_srv_len smallint
  3724.     DECLARE @orig_db_len  smallint
  3725.     DECLARE @MaxCmdsInTranOn int
  3726.  
  3727.     SELECT @date = GETDATE()
  3728.     SELECT @MaxCmdsInTranOn = 0
  3729.     -- Get publisher database id.
  3730.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  3731.         publisher_db = @publisher_db
  3732.     
  3733.     SELECT @MaxCmdsInTranOn = category & 0x40 from master..sysdatabases where dbid = db_id()
  3734.  
  3735.     select @max_offset = 0
  3736.     -- First insert into MS_repl_transactions
  3737.     if(@MaxCmdsInTranOn > 0 )
  3738.     begin
  3739.         select @max_seqno = max(xact_seqno) from MSrepl_transactions 
  3740.                 where publisher_database_id = @publisher_database_id 
  3741.         if substring( @data, 11, 10 ) = substring( @max_seqno, 1, 10 ) -- same tran
  3742.         begin
  3743.             IF convert( int, substring( @data, 25, 4 ) ) = 1 
  3744.                 select @max_offset = substring(@max_seqno, 11, 4) + 1 -- increment offset
  3745.             else
  3746.                 select @max_offset = substring(@max_seqno, 11, 4) -- keep the same offset
  3747.             if (@max_offset > 0)
  3748.                 select @seqno = substring( @data, 11, 10 ) + @max_offset
  3749.             else
  3750.                 select @seqno = substring( @data, 11, 10 )
  3751.         end
  3752.         else
  3753.             select @seqno = substring( @data, 11, 10 )
  3754.     end
  3755.     else
  3756.         select @seqno = substring( @data, 11, 10 )
  3757.     IF convert( int, substring( @data, 25, 4 ) ) = 1  --first command in tran
  3758.         INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3759.                  substring( @data, 1, 10 ), @seqno, @date)
  3760.  
  3761.     if @max_offset is NULL
  3762.         select @max_offset  = 0
  3763.     select @max_offset  = @max_offset + 1
  3764.  
  3765.     IF @1data is null
  3766.       goto INSERT_CMDS
  3767.  
  3768.     if(substring( @1data, 11, 10 ) = substring( @data, 11, 10 )) --same tran
  3769.     begin
  3770.         IF convert( int, substring( @1data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  3771.         begin
  3772.             select @1seqno = substring( @1data, 11, 10 ) + @max_offset
  3773.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3774.                  substring( @1data, 1, 10 ), @1seqno, @date)
  3775.             select @max_offset  = @max_offset + 1
  3776.         end
  3777.         else
  3778.             select @1seqno = @seqno 
  3779.     end
  3780.     else
  3781.     begin
  3782.         select @1seqno = substring( @1data, 11, 10 ) 
  3783.         IF convert( int, substring( @1data, 25, 4 ) ) = 1  
  3784.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3785.                  substring( @1data, 1, 10 ), @1seqno, @date)
  3786.     end
  3787.  
  3788.     IF @2data is null
  3789.       goto INSERT_CMDS
  3790.  
  3791.     if(substring( @2data, 11, 10 ) = substring( @1data, 11, 10 )) --same tran
  3792.     begin
  3793.         IF convert( int, substring( @2data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  3794.         begin
  3795.             select @2seqno = substring( @2data, 11, 10 )+ @max_offset
  3796.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3797.                  substring( @2data, 1, 10 ), @2seqno, @date)
  3798.             select @max_offset  = @max_offset + 1
  3799.         end
  3800.         else
  3801.             select @2seqno = @1seqno 
  3802.     end
  3803.     else
  3804.     begin
  3805.         select @2seqno = substring( @2data, 11, 10 ) 
  3806.         IF convert( int, substring( @2data, 25, 4 ) ) = 1  
  3807.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3808.                  substring( @2data, 1, 10 ), @2seqno, @date)
  3809.     end
  3810.     
  3811.     IF @3data is null
  3812.       goto INSERT_CMDS
  3813.  
  3814.     if(substring( @3data, 11, 10 ) = substring( @2data, 11, 10 )) --same tran
  3815.     begin
  3816.         IF convert( int, substring( @3data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  3817.         begin
  3818.             select @3seqno = substring( @3data, 11, 10 ) + @max_offset 
  3819.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3820.                  substring( @3data, 1, 10 ), @3seqno, @date)
  3821.             select @max_offset  = @max_offset + 1
  3822.         end
  3823.         else
  3824.             select @3seqno = @2seqno 
  3825.     end
  3826.     else
  3827.     begin
  3828.         select @3seqno = substring( @3data, 11, 10 ) 
  3829.         IF convert( int, substring( @3data, 25, 4 ) ) = 1  
  3830.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3831.                  substring( @3data, 1, 10 ), @3seqno, @date)
  3832.     end
  3833.  
  3834.     IF @4data is null
  3835.       goto INSERT_CMDS
  3836.  
  3837.     if(substring( @4data, 11, 10 ) = substring( @3data, 11, 10 )) --same tran
  3838.     begin
  3839.         IF convert( int, substring( @4data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  3840.         begin
  3841.             select @4seqno = substring( @4data, 11, 10 ) + @max_offset
  3842.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3843.                  substring( @4data, 1, 10 ), @4seqno, @date)
  3844.             select @max_offset  = @max_offset + 1
  3845.         end
  3846.         else
  3847.             select @4seqno = @3seqno 
  3848.     end
  3849.     else
  3850.     begin
  3851.         select @4seqno = substring( @4data, 11, 10 ) 
  3852.         IF convert( int, substring( @4data, 25, 4 ) ) = 1  
  3853.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3854.                  substring( @4data, 1, 10 ), @4seqno, @date)
  3855.     end
  3856.  
  3857.     IF @5data is null
  3858.       goto INSERT_CMDS
  3859.     if(substring( @5data, 11, 10 ) = substring( @4data, 11, 10 )) --same tran
  3860.     begin
  3861.         IF convert( int, substring( @5data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  3862.         begin
  3863.             select @5seqno = substring( @5data, 11, 10 ) + @max_offset
  3864.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3865.                  substring( @5data, 1, 10 ), @5seqno, @date)
  3866.             select @max_offset  = @max_offset + 1
  3867.         end
  3868.         else
  3869.             select @5seqno = @4seqno 
  3870.     end
  3871.     else
  3872.     begin
  3873.         select @5seqno = substring( @5data, 11, 10 ) 
  3874.         IF convert( int, substring( @5data, 25, 4 ) ) = 1  
  3875.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3876.                  substring( @5data, 1, 10 ), @5seqno, @date)
  3877.     end
  3878.  
  3879.     IF @6data is null
  3880.       goto INSERT_CMDS
  3881.     if(substring( @6data, 11, 10 ) = substring( @5data, 11, 10 )) --same tran
  3882.     begin
  3883.         IF convert( int, substring( @6data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  3884.         begin
  3885.             select @6seqno = substring( @6data, 11, 10 ) + @max_offset
  3886.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3887.                  substring( @6data, 1, 10 ), @6seqno, @date)
  3888.             select @max_offset  = @max_offset + 1
  3889.         end
  3890.         else
  3891.             select @6seqno = @5seqno 
  3892.     end
  3893.     else
  3894.     begin
  3895.         select @6seqno = substring( @6data, 11, 10 ) 
  3896.         IF convert( int, substring( @6data, 25, 4 ) ) = 1  
  3897.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3898.                  substring( @6data, 1, 10 ), @6seqno, @date)
  3899.     end
  3900.  
  3901.     IF @7data is null
  3902.       goto INSERT_CMDS
  3903.     if(substring( @7data, 11, 10 ) = substring( @6data, 11, 10 )) --same tran
  3904.     begin
  3905.         IF convert( int, substring( @7data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  3906.         begin
  3907.             select @7seqno = substring( @7data, 11, 10 ) + @max_offset
  3908.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3909.                  substring( @7data, 1, 10 ), @7seqno, @date)
  3910.             select @max_offset  = @max_offset + 1
  3911.         end
  3912.         else
  3913.             select @7seqno = @6seqno 
  3914.     end
  3915.     else
  3916.     begin
  3917.         select @7seqno = substring( @7data, 11, 10 ) 
  3918.         IF convert( int, substring( @7data, 25, 4 ) ) = 1  
  3919.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3920.                  substring( @7data, 1, 10 ), @7seqno, @date)
  3921.     end
  3922.  
  3923.     IF @8data is null
  3924.       goto INSERT_CMDS
  3925.     if(substring( @8data, 11, 10 ) = substring( @7data, 11, 10 )) --same tran
  3926.     begin
  3927.         IF convert( int, substring( @8data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  3928.         begin
  3929.             select @8seqno = substring( @8data, 11, 10 ) + @max_offset
  3930.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3931.                  substring( @8data, 1, 10 ), @8seqno, @date)
  3932.             select @max_offset  = @max_offset + 1
  3933.         end
  3934.         else
  3935.             select @8seqno = @7seqno 
  3936.     end
  3937.     else
  3938.     begin
  3939.         select @8seqno = substring( @8data, 11, 10 ) 
  3940.         IF convert( int, substring( @8data, 25, 4 ) ) = 1  
  3941.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3942.                  substring( @8data, 1, 10 ), @8seqno, @date)
  3943.     end
  3944.  
  3945.     IF @9data is null
  3946.       goto INSERT_CMDS
  3947.     if(substring( @9data, 11, 10 ) = substring( @8data, 11, 10 )) --same tran
  3948.     begin
  3949.         IF convert( int, substring( @9data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  3950.         begin
  3951.             select @9seqno = substring( @9data, 11, 10 ) + @max_offset
  3952.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3953.                  substring( @9data, 1, 10 ), @9seqno, @date)
  3954.             select @max_offset  = @max_offset + 1
  3955.         end
  3956.         else
  3957.             select @9seqno = @8seqno 
  3958.     end
  3959.     else
  3960.     begin
  3961.         select @9seqno = substring( @9data, 11, 10 ) 
  3962.         IF convert( int, substring( @9data, 25, 4 ) ) = 1  
  3963.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3964.                  substring( @9data, 1, 10 ), @9seqno, @date)
  3965.     end
  3966.  
  3967.     IF @10data is null
  3968.       goto INSERT_CMDS
  3969.     if(substring( @10data, 11, 10 ) = substring( @9data, 11, 10 )) --same tran
  3970.     begin
  3971.         IF convert( int, substring( @10data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  3972.         begin
  3973.             select @10seqno = substring( @10data, 11, 10 ) + @max_offset
  3974.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3975.                  substring( @10data, 1, 10 ), @10seqno, @date)
  3976.             select @max_offset  = @max_offset + 1
  3977.         end
  3978.         else
  3979.             select @10seqno = @9seqno 
  3980.     end
  3981.     else
  3982.     begin
  3983.         select @10seqno = substring( @10data, 11, 10 ) 
  3984.         IF convert( int, substring( @10data, 25, 4 ) ) = 1  
  3985.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3986.                  substring( @10data, 1, 10 ), @10seqno, @date)
  3987.     end
  3988.  
  3989.     IF @11data is null
  3990.       goto INSERT_CMDS
  3991.     if(substring( @11data, 11, 10 ) = substring( @10data, 11, 10 )) --same tran
  3992.     begin
  3993.         IF convert( int, substring( @11data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  3994.         begin
  3995.             select @11seqno = substring( @11data, 11, 10 )+ @max_offset
  3996.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3997.                  substring( @11data, 1, 10 ), @11seqno, @date)
  3998.             select @max_offset  = @max_offset + 1
  3999.         end
  4000.         else
  4001.             select @11seqno = @10seqno 
  4002.     end
  4003.     else
  4004.     begin
  4005.         select @11seqno = substring( @11data, 11, 10 ) 
  4006.         IF convert( int, substring( @11data, 25, 4 ) ) = 1  
  4007.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4008.                  substring( @11data, 1, 10 ), @11seqno, @date)
  4009.     end
  4010.  
  4011.     IF @12data is null
  4012.       goto INSERT_CMDS
  4013.     if(substring( @12data, 11, 10 ) = substring( @11data, 11, 10 )) --same tran
  4014.     begin
  4015.         IF convert( int, substring( @12data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  4016.         begin
  4017.             select @12seqno = substring( @12data, 11, 10 ) + @max_offset
  4018.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4019.                  substring( @12data, 1, 10 ), @12seqno, @date)
  4020.             select @max_offset  = @max_offset + 1
  4021.         end
  4022.         else
  4023.             select @12seqno = @11seqno 
  4024.     end
  4025.     else
  4026.     begin
  4027.         select @12seqno = substring( @12data, 11, 10 ) 
  4028.         IF convert( int, substring( @12data, 25, 4 ) ) = 1  
  4029.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4030.                  substring( @12data, 1, 10 ), @12seqno, @date)
  4031.     end
  4032.     
  4033.     IF @13data is null
  4034.       goto INSERT_CMDS
  4035. if(substring( @13data, 11, 10 ) = substring( @12data, 11, 10 )) --same tran
  4036.     begin
  4037.         IF convert( int, substring( @13data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  4038.         begin
  4039.             select @13seqno = substring( @13data, 11, 10 ) + @max_offset
  4040.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4041.                  substring( @13data, 1, 10 ), @13seqno, @date)
  4042.             select @max_offset  = @max_offset + 1
  4043.         end
  4044.         else
  4045.             select @13seqno = @12seqno 
  4046.     end
  4047.     else
  4048.     begin
  4049.         select @13seqno = substring( @13data, 11, 10 ) 
  4050.         IF convert( int, substring( @13data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  4051.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4052.                  substring( @13data, 1, 10 ), @13seqno, @date)
  4053.     end
  4054.  
  4055.     IF @14data is null
  4056.       goto INSERT_CMDS
  4057. if(substring( @14data, 11, 10 ) = substring( @13data, 11, 10 )) --same tran
  4058.     begin
  4059.         IF convert( int, substring( @14data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  4060.         begin
  4061.             select @14seqno = substring( @14data, 11, 10 ) + @max_offset
  4062.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4063.                  substring( @14data, 1, 10 ), @14seqno, @date)
  4064.             select @max_offset  = @max_offset + 1
  4065.         end
  4066.         else
  4067.             select @14seqno = @13seqno 
  4068.     end
  4069.     else
  4070.     begin
  4071.         select @14seqno = substring( @14data, 11, 10 ) 
  4072.         IF convert( int, substring( @14data, 25, 4 ) ) = 1  
  4073.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4074.                  substring( @14data, 1, 10 ), @14seqno, @date)
  4075.     end
  4076.  
  4077.     IF @15data is null
  4078.       goto INSERT_CMDS
  4079. if(substring( @15data, 11, 10 ) = substring( @14data, 11, 10 )) --same tran
  4080.     begin
  4081.         IF convert( int, substring( @15data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  4082.         begin
  4083.             select @15seqno = substring( @15data, 11, 10 ) + @max_offset
  4084.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4085.                  substring( @15data, 1, 10 ), @15seqno, @date)
  4086.             select @max_offset  = @max_offset + 1
  4087.         end
  4088.         else
  4089.             select @15seqno = @14seqno 
  4090.     end
  4091.     else
  4092.     begin
  4093.         select @15seqno = substring( @15data, 11, 10 ) 
  4094.         IF convert( int, substring( @15data, 25, 4 ) ) = 1  
  4095.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4096.                  substring( @15data, 1, 10 ), @15seqno, @date)
  4097.     end
  4098.  
  4099.     IF @16data is null
  4100.       goto INSERT_CMDS
  4101. if(substring( @16data, 11, 10 ) = substring( @15data, 11, 10 )) --same tran
  4102.     begin
  4103.         IF convert( int, substring( @16data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  4104.         begin
  4105.             select @16seqno = substring( @16data, 11, 10 ) + @max_offset
  4106.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4107.                  substring( @16data, 1, 10 ), @16seqno, @date)
  4108.             select @max_offset  = @max_offset + 1
  4109.         end
  4110.         else
  4111.             select @16seqno = @15seqno 
  4112.     end
  4113.     else
  4114.     begin
  4115.         select @16seqno = substring( @16data, 11, 10 ) 
  4116.         IF convert( int, substring( @16data, 25, 4 ) ) = 1  
  4117.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4118.                  substring( @16data, 1, 10 ), @16seqno, @date)
  4119.     end
  4120.  
  4121.     IF @17data is null
  4122.       goto INSERT_CMDS
  4123. if(substring( @17data, 11, 10 ) = substring( @16data, 11, 10 )) --same tran
  4124.     begin
  4125.         IF convert( int, substring( @17data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  4126.         begin
  4127.             select @17seqno = substring( @17data, 11, 10 ) + @max_offset
  4128.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4129.                  substring( @17data, 1, 10 ), @17seqno, @date)
  4130.             select @max_offset  = @max_offset + 1
  4131.         end
  4132.         else
  4133.             select @17seqno = @16seqno 
  4134.     end
  4135.     else
  4136.     begin
  4137.         select @17seqno = substring( @17data, 11, 10 ) 
  4138.         IF convert( int, substring( @17data, 25, 4 ) ) = 1  
  4139.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4140.                  substring( @17data, 1, 10 ), @17seqno, @date)
  4141.     end
  4142.  
  4143.     IF @18data is null
  4144.       goto INSERT_CMDS
  4145.     if(substring( @18data, 11, 10 ) = substring( @17data, 11, 10 )) --same tran
  4146.     begin
  4147.         IF convert( int, substring( @18data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  4148.         begin
  4149.             select @18seqno = substring( @18data, 11, 10 )+ @max_offset
  4150.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4151.                  substring( @18data, 1, 10 ), @18seqno, @date)
  4152.             select @max_offset  = @max_offset + 1
  4153.         end
  4154.         else
  4155.             select @18seqno = @17seqno 
  4156.     end
  4157.     else
  4158.     begin
  4159.         select @18seqno = substring( @18data, 11, 10 ) 
  4160.         IF convert( int, substring( @18data, 25, 4 ) ) = 1  
  4161.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4162.                  substring( @18data, 1, 10 ), @18seqno, @date)
  4163.     end
  4164.  
  4165.     IF @19data is null
  4166.       goto INSERT_CMDS
  4167.     if(substring( @19data, 11, 10 ) = substring( @18data, 11, 10 )) --same tran
  4168.     begin
  4169.         IF convert( int, substring( @19data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  4170.         begin
  4171.             select @19seqno = substring( @19data, 11, 10 ) + @max_offset
  4172.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4173.                  substring( @19data, 1, 10 ), @19seqno, @date)
  4174.             select @max_offset  = @max_offset + 1
  4175.         end
  4176.         else
  4177.             select @19seqno = @18seqno 
  4178.     end
  4179.     else
  4180.     begin
  4181.         select @19seqno = substring( @19data, 11, 10 ) 
  4182.         IF convert( int, substring( @19data, 25, 4 ) ) = 1  
  4183.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4184.                  substring( @19data, 1, 10 ), @19seqno, @date)
  4185.     end
  4186.  
  4187.     IF @20data is null
  4188.       goto INSERT_CMDS
  4189.     if(substring( @20data, 11, 10 ) = substring( @19data, 11, 10 )) --same tran
  4190.     begin
  4191.         IF convert( int, substring( @20data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  4192.         begin
  4193.             select @20seqno = substring( @20data, 11, 10 ) + @max_offset
  4194.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4195.                  substring( @20data, 1, 10 ), @20seqno, @date)
  4196.             select @max_offset  = @max_offset + 1
  4197.         end
  4198.         else
  4199.             select @20seqno = @19seqno 
  4200.     end
  4201.     else
  4202.     begin
  4203.         select @20seqno = substring( @20data, 11, 10 ) 
  4204.         IF convert( int, substring( @20data, 25, 4 ) ) = 1  
  4205.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4206.                  substring( @20data, 1, 10 ), @20seqno, @date)
  4207.     end
  4208.  
  4209.     IF @21data is null
  4210.       goto INSERT_CMDS
  4211.     if(substring( @21data, 11, 10 ) = substring( @20data, 11, 10 )) --same tran
  4212.     begin
  4213.         IF convert( int, substring( @21data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  4214.         begin
  4215.             select @21seqno = substring( @21data, 11, 10 ) + @max_offset
  4216.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4217.                  substring( @21data, 1, 10 ), @21seqno, @date)
  4218.             select @max_offset  = @max_offset + 1
  4219.         end
  4220.         else
  4221.             select @21seqno = @20seqno 
  4222.     end
  4223.     else
  4224.     begin
  4225.         select @21seqno = substring( @21data, 11, 10 ) 
  4226.         IF convert( int, substring( @21data, 25, 4 ) ) = 1  
  4227.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4228.                  substring( @21data, 1, 10 ), @21seqno, @date)
  4229.     end
  4230.  
  4231.     IF @22data is null
  4232.       goto INSERT_CMDS
  4233.     if(substring( @22data, 11, 10 ) = substring( @21data, 11, 10 )) --same tran
  4234.     begin
  4235.         IF convert( int, substring( @22data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  4236.         begin
  4237.             select @22seqno = substring( @22data, 11, 10 ) + @max_offset
  4238.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4239.                  substring( @22data, 1, 10 ), @22seqno, @date)
  4240.             select @max_offset  = @max_offset + 1
  4241.         end
  4242.         else
  4243.             select @22seqno = @21seqno 
  4244.     end
  4245.     else
  4246.     begin
  4247.         select @22seqno = substring( @22data, 11, 10 ) 
  4248.         IF convert( int, substring( @22data, 25, 4 ) ) = 1  
  4249.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4250.                  substring( @22data, 1, 10 ), @22seqno, @date)
  4251.     end
  4252.  
  4253.     IF @23data is null
  4254.       goto INSERT_CMDS
  4255.     if(substring( @23data, 11, 10 ) = substring( @22data, 11, 10 )) --same tran
  4256.     begin
  4257.         IF convert( int, substring( @23data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  4258.         begin
  4259.             select @23seqno = substring( @23data, 11, 10 ) + @max_offset
  4260.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4261.                  substring( @23data, 1, 10 ), @23seqno, @date)
  4262.             select @max_offset  = @max_offset + 1
  4263.         end
  4264.         else
  4265.             select @23seqno = @22seqno 
  4266.     end
  4267.     else
  4268.     begin
  4269.         select @23seqno = substring( @23data, 11, 10 ) 
  4270.         IF convert( int, substring( @23data, 25, 4 ) ) = 1  
  4271.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4272.                  substring( @23data, 1, 10 ), @23seqno, @date)
  4273.     end
  4274.  
  4275.     IF @24data is null
  4276.       goto INSERT_CMDS
  4277.     if(substring( @24data, 11, 10 ) = substring( @23data, 11, 10 )) --same tran
  4278.     begin
  4279.         IF convert( int, substring( @24data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  4280.         begin
  4281.             select @24seqno = substring( @24data, 11, 10 ) + @max_offset
  4282.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4283.                  substring( @24data, 1, 10 ), @24seqno, @date)
  4284.             select @max_offset  = @max_offset + 1
  4285.         end
  4286.         else
  4287.             select @24seqno = @23seqno 
  4288.     end
  4289.     else
  4290.     begin
  4291.         select @24seqno = substring( @24data, 11, 10 ) 
  4292.         IF convert( int, substring( @24data, 25, 4 ) ) = 1  
  4293.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4294.                  substring( @24data, 1, 10 ), @24seqno, @date)
  4295.     end
  4296.  
  4297.     IF @25data is null
  4298.       goto INSERT_CMDS
  4299.     if(substring( @25data, 11, 10 ) = substring( @24data, 11, 10 )) --same tran
  4300.     begin
  4301.         IF convert( int, substring( @25data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  4302.         begin
  4303.             select @25seqno = substring( @25data, 11, 10 ) + @max_offset
  4304.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4305.                  substring( @25data, 1, 10 ), @25seqno, @date)
  4306.             select @max_offset  = @max_offset + 1
  4307.         end
  4308.         else
  4309.             select @25seqno = @24seqno 
  4310.     end
  4311.     else
  4312.     begin
  4313.         select @25seqno = substring( @25data, 11, 10 ) 
  4314.         IF convert( int, substring( @25data, 25, 4 ) ) = 1  
  4315.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4316.                  substring( @25data, 1, 10 ), @25seqno, @date)
  4317.     end
  4318.  
  4319.     IF @26data is null
  4320.       goto INSERT_CMDS
  4321.     if(substring( @26data, 11, 10 ) = substring( @25data, 11, 10 )) --same tran
  4322.     begin
  4323.         IF convert( int, substring( @26data, 25, 4 ) ) = 1  --only happens with -MaxCmdsInTran 
  4324.         begin
  4325.             select @26seqno = substring( @26data, 11, 10 ) + @max_offset
  4326.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4327.                  substring( @26data, 1, 10 ), @26seqno, @date)
  4328.             select @max_offset  = @max_offset + 1
  4329.         end
  4330.         else
  4331.             select @26seqno = @25seqno 
  4332.     end
  4333.     else
  4334.     begin
  4335.         select @26seqno = substring( @26data, 11, 10 ) 
  4336.         IF convert( int, substring( @26data, 25, 4 ) ) = 1  
  4337.             INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  4338.                  substring( @26data, 1, 10 ), @26seqno, @date)
  4339.     end
  4340.  
  4341. INSERT_CMDS:
  4342.  
  4343.     if datalength( @data ) > 39
  4344.     begin
  4345.         -- Get the originator_id for the first command 
  4346.         select @cmd_data_len = substring( @data, 34, 2 )
  4347.         select @orig_srv_len = substring( @data, 36, 2 )
  4348.         select @orig_db_len = substring( @data, 38, 2 )
  4349.  
  4350.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4351.         begin 
  4352.             set @originator_id = null 
  4353.             select @originator_id = id from MSrepl_originators where
  4354.                 publisher_database_id = @publisher_database_id 
  4355.                 and UPPER(srvname) = upper(convert(sysname, substring( @data, 40 + @cmd_data_len, @orig_srv_len )))
  4356.                 and dbname = substring( @data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4357.             if @originator_id is null
  4358.             begin
  4359.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4360.                     (@publisher_database_id, substring( @data, 40 + @cmd_data_len, @orig_srv_len ), substring( @data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4361.                 select @originator_id = @@identity
  4362.             end
  4363.         end
  4364.         else
  4365.             select @originator_id = 0
  4366.  
  4367.         select @cmd_type = substring(@data,29,4) 
  4368.         if( @cmd_type in( 37,38 ) )
  4369.         begin
  4370.             select @artid = substring(@data,21,4)
  4371.             select @cmd_type = 38 - @cmd_type
  4372.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @seqno
  4373.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4374.         end
  4375.  
  4376.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4377.             @seqno,
  4378.             @cmd_type, 
  4379.             substring(@data,21,4), 
  4380.             @originator_id, 
  4381.             substring(@data,25,4), 
  4382.             convert(bit,substring(@data,33,1)), 
  4383.             substring(@data,40,@cmd_data_len) )
  4384.  
  4385.     end
  4386.     
  4387.     IF @1data is null
  4388.       return
  4389.     IF datalength( @1data ) > 39
  4390.     begin
  4391.         -- Get the originator_id for the first command 
  4392.         select @cmd_data_len = substring( @1data, 34, 2 )
  4393.         select @orig_srv_len = substring( @1data, 36, 2 )
  4394.         select @orig_db_len = substring( @1data, 38, 2 )
  4395.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4396.         begin 
  4397.             set @originator_id = null 
  4398.             select @originator_id = id from MSrepl_originators where
  4399.                 publisher_database_id = @publisher_database_id 
  4400.                 and UPPER(srvname) = upper(convert(sysname, substring( @1data, 40 + @cmd_data_len, @orig_srv_len )))
  4401.                 and dbname = substring( @1data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4402.             if @originator_id is null
  4403.             begin
  4404.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4405.                     (@publisher_database_id, substring( @1data, 40 + @cmd_data_len, @orig_srv_len ), substring( @1data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4406.                 select @originator_id = @@identity
  4407.             end
  4408.         end
  4409.         else
  4410.             select @originator_id = 0
  4411.  
  4412.         -- Now insert into MSrepl_commands
  4413.         select @cmd_type = substring(@1data,29,4)
  4414.         if( @cmd_type in( 37,38 ) )
  4415.         begin
  4416.             select @artid = substring(@1data,21,4)
  4417.             select @cmd_type = 38 - @cmd_type
  4418.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @1seqno
  4419.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4420.         end
  4421.  
  4422.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4423.             @1seqno, 
  4424.             @cmd_type, 
  4425.             substring(@1data,21,4), 
  4426.             @originator_id, 
  4427.             substring(@1data,25,4), 
  4428.             convert(bit,substring(@1data,33,1)), 
  4429.             substring(@1data,40,@cmd_data_len) )
  4430.     end
  4431.  
  4432.     IF @2data is null
  4433.       return
  4434.     IF datalength( @2data ) > 39
  4435.     begin
  4436.         -- Get the originator_id for the first command 
  4437.         select @cmd_data_len = substring( @2data, 34, 2 )
  4438.         select @orig_srv_len = substring( @2data, 36, 2 )
  4439.         select @orig_db_len = substring( @2data, 38, 2 )
  4440.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4441.         begin 
  4442.             set @originator_id = null 
  4443.             select @originator_id = id from MSrepl_originators where
  4444.                 publisher_database_id = @publisher_database_id 
  4445.                 and UPPER(srvname) = upper(convert(sysname, substring( @2data, 40 + @cmd_data_len, @orig_srv_len )))
  4446.                 and dbname = substring( @2data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4447.             if @originator_id is null
  4448.             begin
  4449.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4450.                     (@publisher_database_id, substring( @2data, 40 + @cmd_data_len, @orig_srv_len ), substring( @2data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4451.                 select @originator_id = @@identity
  4452.             end
  4453.         end
  4454.         else
  4455.             select @originator_id = 0
  4456.  
  4457.         -- Now insert into MSrepl_commands
  4458.         select @cmd_type = substring(@2data,29,4)
  4459.         if( @cmd_type in( 37,38 ) )
  4460.         begin
  4461.             select @artid = substring(@2data,21,4)
  4462.             select @cmd_type = 38 - @cmd_type
  4463.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @2seqno
  4464.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4465.         end
  4466.  
  4467.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4468.             @2seqno,
  4469.             @cmd_type, 
  4470.             substring(@2data,21 ,4), 
  4471.             @originator_id, 
  4472.             substring(@2data,25 ,4), 
  4473.             convert(bit,substring(@2data,33 ,1)), 
  4474.             substring(@2data,40,@cmd_data_len) )
  4475.  
  4476.     end
  4477.  
  4478.     IF @3data is null
  4479.       return
  4480.     IF datalength( @3data ) > 39
  4481.     begin
  4482.         -- Get the originator_id for the first command 
  4483.         select @cmd_data_len = substring( @3data, 34, 2 )
  4484.         select @orig_srv_len = substring( @3data, 36, 2 )
  4485.         select @orig_db_len = substring( @3data, 38, 2 )
  4486.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4487.         begin 
  4488.             set @originator_id = null 
  4489.             select @originator_id = id from MSrepl_originators where
  4490.                 publisher_database_id = @publisher_database_id 
  4491.                 and UPPER(srvname) = upper(convert(sysname, substring( @3data, 40 + @cmd_data_len, @orig_srv_len )))
  4492.                 and dbname = substring( @3data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4493.             if @originator_id is null
  4494.             begin
  4495.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4496.                     (@publisher_database_id, substring( @3data, 40 + @cmd_data_len, @orig_srv_len ), substring( @3data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4497.                 select @originator_id = @@identity
  4498.             end
  4499.         end
  4500.         else
  4501.             select @originator_id = 0
  4502.  
  4503.         -- Now insert into MSrepl_commands
  4504.         select @cmd_type = substring(@3data,29,4)
  4505.         if( @cmd_type in( 37,38 ) )
  4506.         begin
  4507.             select @artid = substring(@3data,21,4)
  4508.             select @cmd_type = 38 - @cmd_type
  4509.             select @xact_seqno = substring( @3data, 11, 10 )
  4510.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @3seqno
  4511.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4512.         end
  4513.  
  4514.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4515.             @3seqno,
  4516.             @cmd_type, 
  4517.             substring(@3data,21 ,4), 
  4518.             @originator_id, 
  4519.             substring(@3data,25 ,4), 
  4520.             convert(bit,substring(@3data,33 ,1)), 
  4521.             substring(@3data,40,@cmd_data_len) )
  4522.  
  4523.     end
  4524.  
  4525.     IF @4data is null
  4526.       return
  4527.     IF datalength( @4data ) > 39
  4528.     begin
  4529.         -- Get the originator_id for the first command 
  4530.         select @cmd_data_len = substring( @4data, 34, 2 )
  4531.         select @orig_srv_len = substring( @4data, 36, 2 )
  4532.         select @orig_db_len = substring( @4data, 38, 2 )
  4533.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4534.         begin 
  4535.             set @originator_id = null 
  4536.             select @originator_id = id from MSrepl_originators where
  4537.                 publisher_database_id = @publisher_database_id 
  4538.                 and UPPER(srvname) = upper(convert(sysname, substring( @4data, 40 + @cmd_data_len, @orig_srv_len )))
  4539.                 and dbname = substring( @4data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4540.             if @originator_id is null
  4541.             begin
  4542.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4543.                     (@publisher_database_id, substring( @4data, 40 + @cmd_data_len, @orig_srv_len ), substring( @4data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4544.                 select @originator_id = @@identity
  4545.             end
  4546.         end
  4547.         else
  4548.             select @originator_id = 0
  4549.  
  4550.         -- Now insert into MSrepl_commands
  4551.         select @cmd_type = substring(@4data,29,4)
  4552.         if( @cmd_type in( 37,38 ) )
  4553.         begin
  4554.             select @artid = substring(@4data,21,4)
  4555.             select @cmd_type = 38 - @cmd_type
  4556.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @4seqno
  4557.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4558.         end
  4559.  
  4560.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4561.             @4seqno,
  4562.             @cmd_type, 
  4563.             substring(@4data,21 ,4), 
  4564.             @originator_id, 
  4565.             substring(@4data,25 ,4), 
  4566.             convert(bit,substring(@4data,33 ,1)), 
  4567.             substring(@4data,40,@cmd_data_len) )
  4568.  
  4569.     end
  4570.  
  4571.     IF @5data is null
  4572.       return
  4573.     IF datalength( @5data ) > 39
  4574.     begin
  4575.         -- Get the originator_id for the first command 
  4576.         select @cmd_data_len = substring( @5data, 34, 2 )
  4577.         select @orig_srv_len = substring( @5data, 36, 2 )
  4578.         select @orig_db_len = substring( @5data, 38, 2 )
  4579.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4580.         begin 
  4581.             set @originator_id = null 
  4582.             select @originator_id = id from MSrepl_originators where
  4583.                 publisher_database_id = @publisher_database_id 
  4584.                 and UPPER(srvname) = upper(convert(sysname, substring( @5data, 40 + @cmd_data_len, @orig_srv_len )))
  4585.                 and dbname = substring( @5data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4586.             if @originator_id is null
  4587.             begin
  4588.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4589.                     (@publisher_database_id, substring( @5data, 40 + @cmd_data_len, @orig_srv_len ), substring( @5data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4590.                 select @originator_id = @@identity
  4591.             end
  4592.         end
  4593.         else
  4594.             select @originator_id = 0
  4595.  
  4596.         -- Now insert into MSrepl_commands
  4597.         select @cmd_type = substring(@5data,29,4)
  4598.         if( @cmd_type in( 37,38 ) )
  4599.         begin
  4600.             select @artid = substring(@5data,21,4)
  4601.             select @cmd_type = 38 - @cmd_type
  4602.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @5seqno
  4603.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4604.         end
  4605.  
  4606.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4607.             @5seqno,
  4608.             @cmd_type, 
  4609.             substring(@5data,21 ,4), 
  4610.             @originator_id, 
  4611.             substring(@5data,25 ,4), 
  4612.             convert(bit,substring(@5data,33 ,1)), 
  4613.             substring(@5data,40,@cmd_data_len) )
  4614.  
  4615.     end
  4616.  
  4617.     IF @6data is null
  4618.       return
  4619.     IF datalength( @6data ) > 39
  4620.     begin
  4621.         -- Get the originator_id for the first command 
  4622.         select @cmd_data_len = substring( @6data, 34, 2 )
  4623.         select @orig_srv_len = substring( @6data, 36, 2 )
  4624.         select @orig_db_len = substring( @6data, 38, 2 )
  4625.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4626.         begin 
  4627.             set @originator_id = null 
  4628.             select @originator_id = id from MSrepl_originators where
  4629.                 publisher_database_id = @publisher_database_id 
  4630.                 and UPPER(srvname) = upper(convert(sysname, substring( @6data, 40 + @cmd_data_len, @orig_srv_len )))
  4631.                 and dbname = substring( @6data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4632.             if @originator_id is null
  4633.             begin
  4634.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4635.                     (@publisher_database_id, substring( @6data, 40 + @cmd_data_len, @orig_srv_len ), substring( @6data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4636.                 select @originator_id = @@identity
  4637.             end
  4638.         end
  4639.         else
  4640.             select @originator_id = 0
  4641.  
  4642.         -- Now insert into MSrepl_commands
  4643.         select @cmd_type = substring(@6data,29,4)
  4644.         if( @cmd_type in( 37,38 ) )
  4645.         begin
  4646.             select @artid = substring(@6data,21,4)
  4647.             select @cmd_type = 38 - @cmd_type
  4648.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @6seqno  
  4649.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4650.         end
  4651.  
  4652.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4653.             @6seqno,
  4654.             @cmd_type, 
  4655.             substring(@6data,21 ,4), 
  4656.             @originator_id, 
  4657.             substring(@6data,25 ,4), 
  4658.             convert(bit,substring(@6data,33 ,1)), 
  4659.             substring(@6data,40,@cmd_data_len) )
  4660.  
  4661.     end
  4662.  
  4663.     IF @7data is null
  4664.       return
  4665.     IF datalength( @7data ) > 39
  4666.     begin
  4667.         -- Get the originator_id for the first command 
  4668.         select @cmd_data_len = substring( @7data, 34, 2 )
  4669.         select @orig_srv_len = substring( @7data, 36, 2 )
  4670.         select @orig_db_len = substring( @7data, 38, 2 )
  4671.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4672.         begin 
  4673.             set @originator_id = null 
  4674.             select @originator_id = id from MSrepl_originators where
  4675.                 publisher_database_id = @publisher_database_id 
  4676.                 and UPPER(srvname) = upper(convert(sysname, substring( @7data, 40 + @cmd_data_len, @orig_srv_len )))
  4677.                 and dbname = substring( @7data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4678.             if @originator_id is null
  4679.             begin
  4680.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4681.                     (@publisher_database_id, substring( @7data, 40 + @cmd_data_len, @orig_srv_len ), substring( @7data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4682.                 select @originator_id = @@identity
  4683.             end
  4684.         end
  4685.         else
  4686.             select @originator_id = 0
  4687.  
  4688.         -- Now insert into MSrepl_commands
  4689.         select @cmd_type = substring(@7data,29,4)
  4690.         if( @cmd_type in( 37,38 ) )
  4691.         begin
  4692.             select @artid = substring(@7data,21,4)
  4693.             select @cmd_type = 38 - @cmd_type
  4694.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @7seqno  
  4695.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4696.         end
  4697.  
  4698.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4699.             @7seqno,
  4700.             @cmd_type, 
  4701.             substring(@7data,21 ,4), 
  4702.             @originator_id, 
  4703.             substring(@7data,25 ,4), 
  4704.             convert(bit,substring(@7data,33 ,1)), 
  4705.             substring(@7data,40,@cmd_data_len) )
  4706.  
  4707.     end
  4708.  
  4709.     IF @8data is null
  4710.       return
  4711.     IF datalength( @8data ) > 39
  4712.     begin
  4713.         -- Get the originator_id for the first command 
  4714.         select @cmd_data_len = substring( @8data, 34, 2 )
  4715.         select @orig_srv_len = substring( @8data, 36, 2 )
  4716.         select @orig_db_len = substring( @8data, 38, 2 )
  4717.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4718.         begin 
  4719.             set @originator_id = null 
  4720.             select @originator_id = id from MSrepl_originators where
  4721.                 publisher_database_id = @publisher_database_id 
  4722.                 and UPPER(srvname) = upper(convert(sysname, substring( @8data, 40 + @cmd_data_len, @orig_srv_len )))
  4723.                 and dbname = substring( @8data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4724.             if @originator_id is null
  4725.             begin
  4726.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4727.                     (@publisher_database_id, substring( @8data, 40 + @cmd_data_len, @orig_srv_len ), substring( @8data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4728.                 select @originator_id = @@identity
  4729.             end
  4730.         end
  4731.         else
  4732.             select @originator_id = 0
  4733.  
  4734.         -- Now insert into MSrepl_commands
  4735.         select @cmd_type = substring(@8data,29,4)
  4736.         if( @cmd_type in( 37,38 ) )
  4737.         begin
  4738.             select @artid = substring(@8data,21,4)
  4739.             select @cmd_type = 38 - @cmd_type
  4740.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @8seqno  
  4741.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4742.         end
  4743.  
  4744.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4745.             @8seqno,
  4746.             @cmd_type, 
  4747.             substring(@8data,21 ,4), 
  4748.             @originator_id, 
  4749.             substring(@8data,25 ,4), 
  4750.             convert(bit,substring(@8data,33 ,1)), 
  4751.             substring(@8data,40,@cmd_data_len) )
  4752.     end
  4753.  
  4754.     IF @9data is null
  4755.       return
  4756.     IF datalength( @9data ) > 39
  4757.     begin
  4758.         -- Get the originator_id for the first command 
  4759.         select @cmd_data_len = substring( @9data, 34, 2 )
  4760.         select @orig_srv_len = substring( @9data, 36, 2 )
  4761.         select @orig_db_len = substring( @9data, 38, 2 )
  4762.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4763.         begin 
  4764.             set @originator_id = null 
  4765.             select @originator_id = id from MSrepl_originators where
  4766.                 publisher_database_id = @publisher_database_id 
  4767.                 and upper(srvname) = upper(convert(sysname, substring( @9data, 40 + @cmd_data_len, @orig_srv_len )))
  4768.                 and dbname = substring( @9data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4769.             if @originator_id is null
  4770.             begin
  4771.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4772.                     (@publisher_database_id, substring( @9data, 40 + @cmd_data_len, @orig_srv_len ), substring( @9data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4773.                 select @originator_id = @@identity
  4774.             end
  4775.         end
  4776.         else
  4777.             select @originator_id = 0
  4778.  
  4779.         -- Now insert into MSrepl_commands
  4780.         select @cmd_type = substring(@9data,29,4)
  4781.         if( @cmd_type in( 37,38 ) )
  4782.         begin
  4783.             select @artid = substring(@9data,21,4)
  4784.             select @cmd_type = 38 - @cmd_type
  4785.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @9seqno  
  4786.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4787.         end
  4788.  
  4789.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4790.             @9seqno,
  4791.             @cmd_type, 
  4792.             substring(@9data,21 ,4), 
  4793.             @originator_id, 
  4794.             substring(@9data,25 ,4), 
  4795.             convert(bit,substring(@9data,33 ,1)), 
  4796.             substring(@9data,40,@cmd_data_len) )
  4797.     end
  4798.  
  4799.     IF @10data is null
  4800.       return
  4801.     IF datalength( @10data ) > 39
  4802.     begin
  4803.         -- Get the originator_id for the first command 
  4804.         select @cmd_data_len = substring( @10data, 34, 2 )
  4805.         select @orig_srv_len = substring( @10data, 36, 2 )
  4806.         select @orig_db_len = substring( @10data, 38, 2 )
  4807.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4808.         begin 
  4809.             set @originator_id = null 
  4810.             select @originator_id = id from MSrepl_originators where
  4811.                 publisher_database_id = @publisher_database_id 
  4812.                 and UPPER(srvname) = upper(convert(sysname, substring( @10data, 40 + @cmd_data_len, @orig_srv_len )))
  4813.                 and dbname = substring( @10data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4814.             if @originator_id is null
  4815.             begin
  4816.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4817.                     (@publisher_database_id, substring( @10data, 40 + @cmd_data_len, @orig_srv_len ), substring( @10data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4818.                 select @originator_id = @@identity
  4819.             end
  4820.         end
  4821.         else
  4822.             select @originator_id = 0
  4823.  
  4824.         -- Now insert into MSrepl_commands
  4825.         select @cmd_type = substring(@10data,29,4)
  4826.         if( @cmd_type in( 37,38 ) )
  4827.         begin
  4828.             select @artid = substring(@10data,21,4)
  4829.             select @cmd_type = 38 - @cmd_type
  4830.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @10seqno  
  4831.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4832.         end
  4833.  
  4834.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4835.             @10seqno,
  4836.             @cmd_type, 
  4837.             substring(@10data,21 ,4), 
  4838.             @originator_id, 
  4839.             substring(@10data,25 ,4), 
  4840.             convert(bit,substring(@10data,33 ,1)), 
  4841.             substring(@10data,40,@cmd_data_len) )
  4842.  
  4843.     end
  4844.  
  4845.     IF @11data is null
  4846.       return
  4847.     IF datalength( @11data ) > 39
  4848.     begin
  4849.         -- Get the originator_id for the first command 
  4850.         select @cmd_data_len = substring( @11data, 34, 2 )
  4851.         select @orig_srv_len = substring( @11data, 36, 2 )
  4852.         select @orig_db_len = substring( @11data, 38, 2 )
  4853.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4854.         begin 
  4855.             set @originator_id = null 
  4856.             select @originator_id = id from MSrepl_originators where
  4857.                 publisher_database_id = @publisher_database_id 
  4858.                 and UPPER(srvname) = upper(convert(sysname, substring( @11data, 40 + @cmd_data_len, @orig_srv_len )))
  4859.                 and dbname = substring( @11data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4860.             if @originator_id is null
  4861.             begin
  4862.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4863.                     (@publisher_database_id, substring( @11data, 40 + @cmd_data_len, @orig_srv_len ), substring( @11data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4864.                 select @originator_id = @@identity
  4865.             end
  4866.         end
  4867.         else
  4868.             select @originator_id = 0
  4869.  
  4870.         -- Now insert into MSrepl_commands
  4871.         select @cmd_type = substring(@11data,29,4)
  4872.         if( @cmd_type in( 37,38 ) )
  4873.         begin
  4874.             select @artid = substring(@11data,21,4)
  4875.             select @cmd_type = 38 - @cmd_type
  4876.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @11seqno  
  4877.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4878.         end
  4879.  
  4880.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4881.             @11seqno,
  4882.             @cmd_type, 
  4883.             substring(@11data,21 ,4), 
  4884.             @originator_id, 
  4885.             substring(@11data,25 ,4), 
  4886.             convert(bit,substring(@11data,33 ,1)), 
  4887.             substring(@11data,40,@cmd_data_len) )
  4888.     end
  4889.  
  4890.     IF @12data is null
  4891.       return
  4892.     IF datalength( @12data ) > 39
  4893.     begin
  4894.         -- Get the originator_id for the first command 
  4895.         select @cmd_data_len = substring( @12data, 34, 2 )
  4896.         select @orig_srv_len = substring( @12data, 36, 2 )
  4897.         select @orig_db_len = substring( @12data, 38, 2 )
  4898.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4899.         begin 
  4900.             set @originator_id = null 
  4901.             select @originator_id = id from MSrepl_originators where
  4902.                 publisher_database_id = @publisher_database_id 
  4903.                 and UPPER(srvname) = upper(convert(sysname, substring( @12data, 40 + @cmd_data_len, @orig_srv_len )))
  4904.                 and dbname = substring( @12data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4905.             if @originator_id is null
  4906.             begin
  4907.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4908.                     (@publisher_database_id, substring( @12data, 40 + @cmd_data_len, @orig_srv_len ), substring( @12data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4909.                 select @originator_id = @@identity
  4910.             end
  4911.         end
  4912.         else
  4913.             select @originator_id = 0
  4914.  
  4915.         -- Now insert into MSrepl_commands
  4916.         select @cmd_type = substring(@12data,29,4)
  4917.         if( @cmd_type in( 37,38 ) )
  4918.         begin
  4919.             select @artid = substring(@12data,21,4)
  4920.             select @cmd_type = 38 - @cmd_type
  4921.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @12seqno  
  4922.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4923.         end
  4924.  
  4925.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4926.             @12seqno,
  4927.             @cmd_type, 
  4928.             substring(@12data,21 ,4), 
  4929.             @originator_id, 
  4930.             substring(@12data,25 ,4), 
  4931.             convert(bit,substring(@12data,33 ,1)), 
  4932.             substring(@12data,40,@cmd_data_len) )
  4933.     end
  4934.  
  4935.  
  4936.     IF @13data is null
  4937.       return
  4938.     IF datalength( @13data ) > 39
  4939.     begin
  4940.         -- Get the originator_id for the first command 
  4941.         select @cmd_data_len = substring( @13data, 34, 2 )
  4942.         select @orig_srv_len = substring( @13data, 36, 2 )
  4943.         select @orig_db_len = substring( @13data, 38, 2 )
  4944.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4945.         begin 
  4946.             set @originator_id = null 
  4947.             select @originator_id = id from MSrepl_originators where
  4948.                 publisher_database_id = @publisher_database_id 
  4949.                 and UPPER(srvname) = upper(convert(sysname, substring( @13data, 40 + @cmd_data_len, @orig_srv_len )))
  4950.                 and dbname = substring( @13data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4951.             if @originator_id is null
  4952.             begin
  4953.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4954.                     (@publisher_database_id, substring( @13data, 40 + @cmd_data_len, @orig_srv_len ), substring( @13data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4955.                 select @originator_id = @@identity
  4956.             end
  4957.         end
  4958.         else
  4959.             select @originator_id = 0
  4960.  
  4961.         -- Now insert into MSrepl_commands
  4962.         select @cmd_type = substring(@13data,29,4)
  4963.         if( @cmd_type in( 37,38 ) )
  4964.         begin
  4965.             select @artid = substring(@13data,21,4)
  4966.             select @cmd_type = 38 - @cmd_type
  4967.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @13seqno  
  4968.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4969.         end
  4970.  
  4971.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4972.             @13seqno,
  4973.             @cmd_type, 
  4974.             substring(@13data,21 ,4), 
  4975.             @originator_id, 
  4976.             substring(@13data,25 ,4), 
  4977.             convert(bit,substring(@13data,33 ,1)), 
  4978.             substring(@13data,40,@cmd_data_len) )
  4979.     end
  4980.  
  4981.     IF @14data is null
  4982.       return
  4983.     IF datalength( @14data ) > 39
  4984.     begin
  4985.         -- Get the originator_id for the first command 
  4986.         select @cmd_data_len = substring( @14data, 34, 2 )
  4987.         select @orig_srv_len = substring( @14data, 36, 2 )
  4988.         select @orig_db_len = substring( @14data, 38, 2 )
  4989.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4990.         begin 
  4991.             set @originator_id = null 
  4992.             select @originator_id = id from MSrepl_originators where
  4993.                 publisher_database_id = @publisher_database_id 
  4994.                 and UPPER(srvname) = upper(convert(sysname, substring( @14data, 40 + @cmd_data_len, @orig_srv_len )))
  4995.                 and dbname = substring( @14data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4996.             if @originator_id is null
  4997.             begin
  4998.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4999.                     (@publisher_database_id, substring( @14data, 40 + @cmd_data_len, @orig_srv_len ), substring( @14data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  5000.                 select @originator_id = @@identity
  5001.             end
  5002.         end
  5003.         else
  5004.             select @originator_id = 0
  5005.  
  5006.         -- Now insert into MSrepl_commands
  5007.         select @cmd_type = substring(@14data,29,4)
  5008.         if( @cmd_type in( 37,38 ) )
  5009.         begin
  5010.             select @artid = substring(@14data,21,4)
  5011.             select @cmd_type = 38 - @cmd_type
  5012.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @14seqno  
  5013.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  5014.         end
  5015.  
  5016.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  5017.             @14seqno,
  5018.             @cmd_type, 
  5019.             substring(@14data,21 ,4), 
  5020.             @originator_id, 
  5021.             substring(@14data,25 ,4), 
  5022.             convert(bit,substring(@14data,33 ,1)), 
  5023.             substring(@14data,40,@cmd_data_len) )
  5024.     end
  5025.  
  5026.  
  5027.     IF @15data is null
  5028.       return
  5029.     IF datalength( @15data ) > 39
  5030.     begin
  5031.         -- Get the originator_id for the first command 
  5032.         select @cmd_data_len = substring( @15data, 34, 2 )
  5033.         select @orig_srv_len = substring( @15data, 36, 2 )
  5034.         select @orig_db_len = substring( @15data, 38, 2 )
  5035.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  5036.         begin 
  5037.             set @originator_id = null 
  5038.             select @originator_id = id from MSrepl_originators where
  5039.                 publisher_database_id = @publisher_database_id 
  5040.                 and UPPER(srvname) = upper(convert(sysname, substring( @15data, 40 + @cmd_data_len, @orig_srv_len )))
  5041.                 and dbname = substring( @15data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  5042.             if @originator_id is null
  5043.             begin
  5044.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  5045.                     (@publisher_database_id, substring( @15data, 40 + @cmd_data_len, @orig_srv_len ), substring( @15data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  5046.                 select @originator_id = @@identity
  5047.             end
  5048.         end
  5049.         else
  5050.             select @originator_id = 0
  5051.  
  5052.         -- Now insert into MSrepl_commands
  5053.         select @cmd_type = substring(@15data,29,4)
  5054.         if( @cmd_type in( 37,38 ) )
  5055.         begin
  5056.             select @artid = substring(@15data,21,4)
  5057.             select @cmd_type = 38 - @cmd_type
  5058.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @15seqno  
  5059.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  5060.         end
  5061.  
  5062.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  5063.             @15seqno,
  5064.             @cmd_type, 
  5065.             substring(@15data,21 ,4), 
  5066.             @originator_id, 
  5067.             substring(@15data,25 ,4), 
  5068.             convert(bit,substring(@15data,33 ,1)), 
  5069.             substring(@15data,40,@cmd_data_len) )
  5070.     end
  5071.  
  5072.     IF @16data is null
  5073.       return
  5074.     IF datalength( @16data ) > 39
  5075.     begin
  5076.         -- Get the originator_id for the first command 
  5077.         select @cmd_data_len = substring( @16data, 34, 2 )
  5078.         select @orig_srv_len = substring( @16data, 36, 2 )
  5079.         select @orig_db_len = substring( @16data, 38, 2 )
  5080.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  5081.         begin 
  5082.             set @originator_id = null 
  5083.             select @originator_id = id from MSrepl_originators where
  5084.                 publisher_database_id = @publisher_database_id 
  5085.                 and UPPER(srvname) = upper(convert(sysname, substring( @16data, 40 + @cmd_data_len, @orig_srv_len )))
  5086.                 and dbname = substring( @16data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  5087.             if @originator_id is null
  5088.             begin
  5089.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  5090.                     (@publisher_database_id, substring( @16data, 40 + @cmd_data_len, @orig_srv_len ), substring( @16data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  5091.                 select @originator_id = @@identity
  5092.             end
  5093.         end
  5094.         else
  5095.             select @originator_id = 0
  5096.  
  5097.         -- Now insert into MSrepl_commands
  5098.         select @cmd_type = substring(@16data,29,4)
  5099.         if( @cmd_type in( 37,38 ) )
  5100.         begin
  5101.             select @artid = substring(@16data,21,4)
  5102.             select @cmd_type = 38 - @cmd_type
  5103.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @16seqno  
  5104.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  5105.         end
  5106.  
  5107.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  5108.             @16seqno,
  5109.             @cmd_type, 
  5110.             substring(@16data,21 ,4), 
  5111.             @originator_id, 
  5112.             substring(@16data,25 ,4), 
  5113.             convert(bit,substring(@16data,33 ,1)), 
  5114.             substring(@16data,40,@cmd_data_len) )
  5115.     end
  5116.  
  5117.  
  5118.     IF @17data is null
  5119.       return
  5120.     IF datalength( @17data ) > 39
  5121.     begin
  5122.         -- Get the originator_id for the first command 
  5123.         select @cmd_data_len = substring( @17data, 34, 2 )
  5124.         select @orig_srv_len = substring( @17data, 36, 2 )
  5125.         select @orig_db_len = substring( @17data, 38, 2 )
  5126.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  5127.         begin 
  5128.             set @originator_id = null 
  5129.             select @originator_id = id from MSrepl_originators where
  5130.                 publisher_database_id = @publisher_database_id 
  5131.                 and UPPER(srvname) = upper(convert(sysname, substring( @17data, 40 + @cmd_data_len, @orig_srv_len )))
  5132.                 and dbname = substring( @17data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  5133.             if @originator_id is null
  5134.             begin
  5135.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  5136.                     (@publisher_database_id, substring( @17data, 40 + @cmd_data_len, @orig_srv_len ), substring( @17data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  5137.                 select @originator_id = @@identity
  5138.             end
  5139.         end
  5140.         else
  5141.             select @originator_id = 0
  5142.  
  5143.         -- Now insert into MSrepl_commands
  5144.         select @cmd_type = substring(@17data,29,4)
  5145.         if( @cmd_type in( 37,38 ) )
  5146.         begin
  5147.             select @artid = substring(@17data,21,4)
  5148.             select @cmd_type = 38 - @cmd_type
  5149.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @17seqno  
  5150.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  5151.         end
  5152.  
  5153.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  5154.             @17seqno,
  5155.             @cmd_type, 
  5156.             substring(@17data,21 ,4), 
  5157.             @originator_id, 
  5158.             substring(@17data,25 ,4), 
  5159.             convert(bit,substring(@17data,33 ,1)), 
  5160.             substring(@17data,40,@cmd_data_len) )
  5161.     end
  5162.  
  5163.  
  5164.     IF @18data is null
  5165.       return
  5166.     IF datalength( @18data ) > 39
  5167.     begin
  5168.         -- Get the originator_id for the first command 
  5169.         select @cmd_data_len = substring( @18data, 34, 2 )
  5170.         select @orig_srv_len = substring( @18data, 36, 2 )
  5171.         select @orig_db_len = substring( @18data, 38, 2 )
  5172.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  5173.         begin 
  5174.             set @originator_id = null 
  5175.             select @originator_id = id from MSrepl_originators where
  5176.                 publisher_database_id = @publisher_database_id 
  5177.                 and UPPER(srvname) = upper(convert(sysname, substring( @18data, 40 + @cmd_data_len, @orig_srv_len )))
  5178.                 and dbname = substring( @18data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  5179.             if @originator_id is null
  5180.             begin
  5181.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  5182.                     (@publisher_database_id, substring( @18data, 40 + @cmd_data_len, @orig_srv_len ), substring( @18data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  5183.                 select @originator_id = @@identity
  5184.             end
  5185.         end
  5186.         else
  5187.             select @originator_id = 0
  5188.  
  5189.         -- Now insert into MSrepl_commands
  5190.         select @cmd_type = substring(@18data,29,4)
  5191.         if( @cmd_type in( 37,38 ) )
  5192.         begin
  5193.             select @artid = substring(@18data,21,4)
  5194.             select @cmd_type = 38 - @cmd_type
  5195.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @18seqno  
  5196.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  5197.         end
  5198.  
  5199.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  5200.             @18seqno,
  5201.             @cmd_type, 
  5202.             substring(@18data,21 ,4), 
  5203.             @originator_id, 
  5204.             substring(@18data,25 ,4), 
  5205.             convert(bit,substring(@18data,33 ,1)), 
  5206.             substring(@18data,40,@cmd_data_len) )
  5207.     end
  5208.  
  5209.  
  5210.     IF @19data is null
  5211.       return
  5212.     IF datalength( @19data ) > 39
  5213.     begin
  5214.         -- Get the originator_id for the first command 
  5215.         select @cmd_data_len = substring( @19data, 34, 2 )
  5216.         select @orig_srv_len = substring( @19data, 36, 2 )
  5217.         select @orig_db_len = substring( @19data, 38, 2 )
  5218.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  5219.         begin 
  5220.             set @originator_id = null 
  5221.             select @originator_id = id from MSrepl_originators where
  5222.                 publisher_database_id = @publisher_database_id 
  5223.                 and UPPER(srvname) = upper(convert(sysname, substring( @19data, 40 + @cmd_data_len, @orig_srv_len )))
  5224.                 and dbname = substring( @19data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  5225.             if @originator_id is null
  5226.             begin
  5227.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  5228.                     (@publisher_database_id, substring( @19data, 40 + @cmd_data_len, @orig_srv_len ), substring( @19data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  5229.                 select @originator_id = @@identity
  5230.             end
  5231.         end
  5232.         else
  5233.             select @originator_id = 0
  5234.  
  5235.         -- Now insert into MSrepl_commands
  5236.         select @cmd_type = substring(@19data,29,4)
  5237.         if( @cmd_type in( 37,38 ) )
  5238.         begin
  5239.             select @artid = substring(@19data,21,4)
  5240.             select @cmd_type = 38 - @cmd_type
  5241.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @19seqno  
  5242.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  5243.         end
  5244.  
  5245.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  5246.             @19seqno,
  5247.             @cmd_type, 
  5248.             substring(@19data,21 ,4), 
  5249.             @originator_id, 
  5250.             substring(@19data,25 ,4), 
  5251.             convert(bit,substring(@19data,33 ,1)), 
  5252.             substring(@19data,40,@cmd_data_len) )
  5253.     end
  5254.  
  5255.  
  5256.     IF @20data is null
  5257.       return
  5258.     IF datalength( @20data ) > 39
  5259.     begin
  5260.         -- Get the originator_id for the first command 
  5261.         select @cmd_data_len = substring( @20data, 34, 2 )
  5262.         select @orig_srv_len = substring( @20data, 36, 2 )
  5263.         select @orig_db_len = substring( @20data, 38, 2 )
  5264.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  5265.         begin 
  5266.             set @originator_id = null 
  5267.             select @originator_id = id from MSrepl_originators where
  5268.                 publisher_database_id = @publisher_database_id 
  5269.                 and UPPER(srvname) = upper(convert(sysname, substring( @20data, 40 + @cmd_data_len, @orig_srv_len )))
  5270.                 and dbname = substring( @20data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  5271.             if @originator_id is null
  5272.             begin
  5273.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  5274.                     (@publisher_database_id, substring( @20data, 40 + @cmd_data_len, @orig_srv_len ), substring( @20data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  5275.                 select @originator_id = @@identity
  5276.             end
  5277.         end
  5278.         else
  5279.             select @originator_id = 0
  5280.  
  5281.         -- Now insert into MSrepl_commands
  5282.         select @cmd_type = substring(@20data,29,4)
  5283.         if( @cmd_type in( 37,38 ) )
  5284.         begin
  5285.             select @artid = substring(@20data,21,4)
  5286.             select @cmd_type = 38 - @cmd_type
  5287.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @20seqno  
  5288.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  5289.         end
  5290.  
  5291.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  5292.             @20seqno,
  5293.             @cmd_type, 
  5294.             substring(@20data,21 ,4), 
  5295.             @originator_id, 
  5296.             substring(@20data,25 ,4), 
  5297.             convert(bit,substring(@20data,33 ,1)), 
  5298.             substring(@20data,40,@cmd_data_len) )
  5299.     end
  5300.  
  5301.     IF @21data is null
  5302.       return
  5303.     IF datalength( @21data ) > 39
  5304.     begin
  5305.         -- Get the originator_id for the first command 
  5306.         select @cmd_data_len = substring( @21data, 34, 2 )
  5307.         select @orig_srv_len = substring( @21data, 36, 2 )
  5308.         select @orig_db_len = substring( @21data, 38, 2 )
  5309.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  5310.         begin 
  5311.             set @originator_id = null 
  5312.             select @originator_id = id from MSrepl_originators where
  5313.                 publisher_database_id = @publisher_database_id 
  5314.                 and UPPER(srvname) = upper(convert(sysname, substring( @21data, 40 + @cmd_data_len, @orig_srv_len )))
  5315.                 and dbname = substring( @21data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  5316.             if @originator_id is null
  5317.             begin
  5318.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  5319.                     (@publisher_database_id, substring( @21data, 40 + @cmd_data_len, @orig_srv_len ), substring( @21data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  5320.                 select @originator_id = @@identity
  5321.             end
  5322.         end
  5323.         else
  5324.             select @originator_id = 0
  5325.  
  5326.         -- Now insert into MSrepl_commands
  5327.         select @cmd_type = substring(@21data,29,4)
  5328.         if( @cmd_type in( 37,38 ) )
  5329.         begin
  5330.             select @artid = substring(@21data,21,4)
  5331.             select @cmd_type = 38 - @cmd_type
  5332.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @21seqno  
  5333.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  5334.         end
  5335.  
  5336.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  5337.             @21seqno,
  5338.             @cmd_type, 
  5339.             substring(@21data,21 ,4), 
  5340.             @originator_id, 
  5341.             substring(@21data,25 ,4), 
  5342.             convert(bit,substring(@21data,33 ,1)), 
  5343.             substring(@21data,40,@cmd_data_len) )
  5344.     end
  5345.  
  5346.     IF @22data is null
  5347.       return
  5348.     IF datalength( @22data ) > 39
  5349.     begin
  5350.         -- Get the originator_id for the first command 
  5351.         select @cmd_data_len = substring( @22data, 34, 2 )
  5352.         select @orig_srv_len = substring( @22data, 36, 2 )
  5353.         select @orig_db_len = substring( @22data, 38, 2 )
  5354.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  5355.         begin 
  5356.             set @originator_id = null 
  5357.             select @originator_id = id from MSrepl_originators where
  5358.                 publisher_database_id = @publisher_database_id 
  5359.                 and UPPER(srvname) = upper(convert(sysname, substring( @22data, 40 + @cmd_data_len, @orig_srv_len )))
  5360.                 and dbname = substring( @22data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  5361.             if @originator_id is null
  5362.             begin
  5363.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  5364.                     (@publisher_database_id, substring( @22data, 40 + @cmd_data_len, @orig_srv_len ), substring( @22data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  5365.                 select @originator_id = @@identity
  5366.             end
  5367.         end
  5368.         else
  5369.             select @originator_id = 0
  5370.  
  5371.         -- Now insert into MSrepl_commands
  5372.         select @cmd_type = substring(@22data,29,4)
  5373.         if( @cmd_type in( 37,38 ) )
  5374.         begin
  5375.             select @artid = substring(@22data,21,4)
  5376.             select @cmd_type = 38 - @cmd_type
  5377.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @22seqno  
  5378.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  5379.         end
  5380.  
  5381.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  5382.             @22seqno,
  5383.             @cmd_type, 
  5384.             substring(@22data,21 ,4), 
  5385.             @originator_id, 
  5386.             substring(@22data,25 ,4), 
  5387.             convert(bit,substring(@22data,33 ,1)), 
  5388.             substring(@22data,40,@cmd_data_len) )
  5389.     end
  5390.  
  5391.     IF @23data is null
  5392.       return
  5393.     IF datalength( @23data ) > 39
  5394.     begin
  5395.         -- Get the originator_id for the first command 
  5396.         select @cmd_data_len = substring( @23data, 34, 2 )
  5397.         select @orig_srv_len = substring( @23data, 36, 2 )
  5398.         select @orig_db_len = substring( @23data, 38, 2 )
  5399.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  5400.         begin 
  5401.             set @originator_id = null 
  5402.             select @originator_id = id from MSrepl_originators where
  5403.                 publisher_database_id = @publisher_database_id 
  5404.                 and UPPER(srvname) = upper(convert(sysname, substring( @23data, 40 + @cmd_data_len, @orig_srv_len )))
  5405.                 and dbname = substring( @23data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  5406.             if @originator_id is null
  5407.             begin
  5408.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  5409.                     (@publisher_database_id, substring( @23data, 40 + @cmd_data_len, @orig_srv_len ), substring( @23data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  5410.                 select @originator_id = @@identity
  5411.             end
  5412.         end
  5413.         else
  5414.             select @originator_id = 0
  5415.  
  5416.         -- Now insert into MSrepl_commands
  5417.         select @cmd_type = substring(@23data,29,4)
  5418.         if( @cmd_type in( 37,38 ) )
  5419.         begin
  5420.             select @artid = substring(@23data,21,4)
  5421.             select @cmd_type = 38 - @cmd_type
  5422.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @23seqno  
  5423.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  5424.         end
  5425.  
  5426.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  5427.             @23seqno,
  5428.             @cmd_type, 
  5429.             substring(@23data,21 ,4), 
  5430.             @originator_id, 
  5431.             substring(@23data,25 ,4), 
  5432.             convert(bit,substring(@23data,33 ,1)), 
  5433.             substring(@23data,40,@cmd_data_len) )
  5434.     end
  5435.  
  5436.     IF @24data is null
  5437.       return
  5438.     IF datalength( @24data ) > 39
  5439.     begin
  5440.         -- Get the originator_id for the first command 
  5441.         select @cmd_data_len = substring( @24data, 34, 2 )
  5442.         select @orig_srv_len = substring( @24data, 36, 2 )
  5443.         select @orig_db_len = substring( @24data, 38, 2 )
  5444.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  5445.         begin 
  5446.             set @originator_id = null 
  5447.             select @originator_id = id from MSrepl_originators where
  5448.                 publisher_database_id = @publisher_database_id 
  5449.                 and UPPER(srvname) = upper(convert(sysname, substring( @24data, 40 + @cmd_data_len, @orig_srv_len )))
  5450.                 and dbname = substring( @24data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  5451.             if @originator_id is null
  5452.             begin
  5453.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  5454.                     (@publisher_database_id, substring( @24data, 40 + @cmd_data_len, @orig_srv_len ), substring( @24data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  5455.                 select @originator_id = @@identity
  5456.             end
  5457.         end
  5458.         else
  5459.             select @originator_id = 0
  5460.  
  5461.         -- Now insert into MSrepl_commands
  5462.         select @cmd_type = substring(@24data,29,4)
  5463.         if( @cmd_type in( 37,38 ) )
  5464.         begin
  5465.             select @artid = substring(@24data,21,4)
  5466.             select @cmd_type = 38 - @cmd_type
  5467.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @24seqno  
  5468.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  5469.         end
  5470.  
  5471.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  5472.             @24seqno,
  5473.             @cmd_type, 
  5474.             substring(@24data,21 ,4), 
  5475.             @originator_id, 
  5476.             substring(@24data,25 ,4), 
  5477.             convert(bit,substring(@24data,33 ,1)), 
  5478.             substring(@24data,40,@cmd_data_len) )
  5479.     end
  5480.  
  5481.  
  5482.     IF @25data is null
  5483.       return
  5484.     IF datalength( @25data ) > 39
  5485.     begin
  5486.         -- Get the originator_id for the first command 
  5487.         select @cmd_data_len = substring( @25data, 34, 2 )
  5488.         select @orig_srv_len = substring( @25data, 36, 2 )
  5489.         select @orig_db_len = substring( @25data, 38, 2 )
  5490.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  5491.         begin 
  5492.             set @originator_id = null 
  5493.             select @originator_id = id from MSrepl_originators where
  5494.                 publisher_database_id = @publisher_database_id 
  5495.                 and UPPER(srvname) = upper(convert(sysname, substring( @25data, 40 + @cmd_data_len, @orig_srv_len )))
  5496.                 and dbname = substring( @25data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  5497.             if @originator_id is null
  5498.             begin
  5499.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  5500.                     (@publisher_database_id, substring( @25data, 40 + @cmd_data_len, @orig_srv_len ), substring( @25data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  5501.                 select @originator_id = @@identity
  5502.             end
  5503.         end
  5504.         else
  5505.             select @originator_id = 0
  5506.  
  5507.         -- Now insert into MSrepl_commands
  5508.         select @cmd_type = substring(@25data,29,4)
  5509.         if( @cmd_type in( 37,38 ) )
  5510.         begin
  5511.             select @artid = substring(@25data,21,4)
  5512.             select @cmd_type = 38 - @cmd_type
  5513.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @25seqno  
  5514.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  5515.         end
  5516.  
  5517.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  5518.             @25seqno,
  5519.             @cmd_type, 
  5520.             substring(@25data,21 ,4), 
  5521.             @originator_id, 
  5522.             substring(@25data,25 ,4), 
  5523.             convert(bit,substring(@25data,33 ,1)), 
  5524.             substring(@25data,40,@cmd_data_len) )
  5525.     end
  5526.  
  5527.  
  5528.     IF @26data is null
  5529.       return
  5530.     IF datalength( @26data ) > 39
  5531.     begin
  5532.         -- Get the originator_id for the first command 
  5533.         select @cmd_data_len = substring( @26data, 34, 2 )
  5534.         select @orig_srv_len = substring( @26data, 36, 2 )
  5535.         select @orig_db_len = substring( @26data, 38, 2 )
  5536.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  5537.         begin 
  5538.             set @originator_id = null 
  5539.             select @originator_id = id from MSrepl_originators where
  5540.                 publisher_database_id = @publisher_database_id 
  5541.                 and UPPER(srvname) = upper(convert(sysname, substring( @26data, 40 + @cmd_data_len, @orig_srv_len )))
  5542.                 and dbname = substring( @26data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  5543.             if @originator_id is null
  5544.             begin
  5545.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  5546.                     (@publisher_database_id, substring( @26data, 40 + @cmd_data_len, @orig_srv_len ), substring( @26data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  5547.                 select @originator_id = @@identity
  5548.             end
  5549.         end
  5550.         else
  5551.             select @originator_id = 0
  5552.  
  5553.         -- Now insert into MSrepl_commands
  5554.         select @cmd_type = substring(@26data,29,4)
  5555.         if( @cmd_type in( 37,38 ) )
  5556.         begin
  5557.             select @artid = substring(@26data,21,4)
  5558.             select @cmd_type = 38 - @cmd_type
  5559.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @26seqno  
  5560.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  5561.         end
  5562.  
  5563.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  5564.             @26seqno,
  5565.             @cmd_type, 
  5566.             substring(@26data,21 ,4), 
  5567.             @originator_id, 
  5568.             substring(@26data,25 ,4), 
  5569.             convert(bit,substring(@26data,33 ,1)), 
  5570.             substring(@26data,40,@cmd_data_len) )
  5571.     end
  5572.  
  5573.  
  5574.     IF @@ERROR <> 0
  5575.       return (1)
  5576.  
  5577. go
  5578.  
  5579.  
  5580. raiserror(15339,-1,-1,'sp_MSvalidate_distpublisher')
  5581. go
  5582. CREATE PROCEDURE sp_MSvalidate_distpublisher
  5583. @publisher sysname,
  5584. @publisher_id smallint = NULL OUTPUT
  5585. as
  5586.  
  5587.     set nocount on
  5588.  
  5589.     declare @distribution_db sysname
  5590.     declare @retcode int
  5591.  
  5592.     -- Check if publisher is a defined as a distribution publisher at this distributor
  5593.     select @publisher_id = srvid from master.dbo.sysservers where UPPER(srvname) = UPPER(@publisher) 
  5594.     if @publisher_id is NULL
  5595.     begin
  5596.         raiserror (14080, 11, -1)
  5597.         return (1)
  5598.     end
  5599.  
  5600.     if not exists (select * from msdb..MSdistpublishers where UPPER(name) = UPPER(@publisher))
  5601.     begin
  5602.         raiserror (14080, 11, -1)
  5603.         return (1)
  5604.     end
  5605.  
  5606.  
  5607.     -- Check if client is in the correct distribution database
  5608.     exec @retcode = dbo.sp_helpdistributor @publisher = @publisher, @distribdb = @distribution_db OUTPUT
  5609.     if @@error <> 0 OR @retcode <> 0
  5610.     begin
  5611.         raiserror (14071, 16, -1)
  5612.         return (1)
  5613.     end
  5614.  
  5615.     -- Check if publisher is associated with a distribution database
  5616.     if @distribution_db is NULL
  5617.     begin
  5618.         raiserror (14071, 16, -1)
  5619.         return(1)
  5620.     end
  5621.  
  5622.     -- Check if client is in the distribution database 
  5623.     if @distribution_db <> db_name()
  5624.     begin
  5625.         raiserror(14071, 16, -1)
  5626.         return(1)
  5627.     end
  5628.  
  5629. go
  5630.  
  5631. raiserror(15339,-1,-1,'sp_MSdrop_distribution_agent')
  5632. GO
  5633. CREATE PROCEDURE sp_MSdrop_distribution_agent (
  5634.     @publisher_id smallint,
  5635.     @publisher_db sysname,
  5636.     @publication sysname,
  5637.     @subscriber_id smallint,
  5638.     @subscriber_db sysname,
  5639.     @subscription_type int,
  5640.     @keep_for_last_run          bit = 0
  5641. AS
  5642. BEGIN
  5643.  
  5644.     SET NOCOUNT ON
  5645.  
  5646.     /*
  5647.     ** Declarations.
  5648.     */
  5649.     DECLARE @stopcode       int
  5650.             ,@retcode        int
  5651.             ,@job_id         binary(16)
  5652.             ,@is_continuous  bit
  5653.             ,@local_job      bit
  5654.             ,@publisher      sysname
  5655.             ,@schedule_name  sysname
  5656.             ,@job_command    nvarchar(512)
  5657.             ,@name           nvarchar(100)
  5658.             ,@agent_id       int
  5659.             ,@queue_id        sysname
  5660.             ,@qservicestatus int
  5661.             ,@qservername    nvarchar(255)
  5662.  
  5663.     select @stopcode = 1
  5664.             ,@qservername = queue_server
  5665.             ,@job_id = job_id, @local_job = local_job, @name = name, @agent_id = id,
  5666.             @queue_id = queue_id
  5667.     FROM MSdistribution_agents WHERE
  5668.         publisher_id = @publisher_id AND
  5669.         publisher_db = @publisher_db AND
  5670.         publication = @publication and
  5671.         subscriber_id = @subscriber_id and
  5672.         subscriber_db = @subscriber_db and
  5673.         subscription_type = @subscription_type
  5674.     
  5675.     -- Delete Perfmon instance
  5676.     dbcc deleteinstance ("SQL Replication Distribution", @name)
  5677.  
  5678.     select @publisher = srvname from master..sysservers where srvid = @publisher_id
  5679.  
  5680.     -- Return if not exists
  5681.     IF @local_job IS NULL
  5682.         RETURN(0)
  5683.  
  5684.     BEGIN TRAN
  5685.  
  5686.     if ((@queue_id is not null) and (@queue_id != N'mssqlqueue'))
  5687.     begin
  5688.         --
  5689.         -- Check if the MSMQ service is running, if not running, return with error
  5690.         -- BYPASS the check for clusters
  5691.         --
  5692.         if ( SERVERPROPERTY('IsClustered') = 0 )
  5693.         begin
  5694.             exec @retcode = master.dbo.xp_controlqueueservice 
  5695.                                 @control_command = 1,
  5696.                                 @return_result = @qservicestatus output
  5697.             if (@retcode != 0 or @@error != 0)
  5698.             begin
  5699.                 raiserror('sp_MSdrop_distribution_agent(debug): xp_controlqueueservice failed in check mode', 16, 1)
  5700.                 GOTO UNDO
  5701.             end
  5702.             
  5703.             if (@qservicestatus != 1)
  5704.             begin
  5705.                 raiserror('sp_MSdrop_distribution_agent(debug): MSMQ service not running', 16, 1)
  5706.                 GOTO UNDO
  5707.             end
  5708.         end
  5709.  
  5710.         --
  5711.         -- delete the local private queue
  5712.         --            
  5713.         exec @retcode = master.dbo.xp_deleteprivatequeue @qservername, @queue_id
  5714.         IF @@ERROR != 0 or @retcode != 0
  5715.         BEGIN
  5716.             RAISERROR('Debug: xp_deleteprivatequeue failed', -1, -1) WITH NOWAIT
  5717.             GOTO UNDO
  5718.         END
  5719.     end
  5720.  
  5721.     IF @local_job = 1 and @keep_for_last_run = 0
  5722.     BEGIN
  5723.         IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  5724.         BEGIN
  5725.             EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  5726.             IF @@ERROR <> 0 or @retcode <> 0
  5727.                 GOTO UNDO
  5728.         END
  5729.     END
  5730.  
  5731.     IF @local_job = 1 and @keep_for_last_run = 1
  5732.     BEGIN
  5733.             select @job_command=command from msdb.dbo.sysjobsteps where job_id=@job_id and step_id=2
  5734.  
  5735.             if PATINDEX('%-[Cc][Oo][Nn][Tt][Ii][Nn][Uu][Oo][Uu][Ss]%', @job_command) > 0
  5736.                 begin
  5737.                     select @is_continuous = 1
  5738.                     create table #sqlstatus(status nvarchar(20))
  5739.                     insert into #sqlstatus (status) exec master.dbo.xp_servicecontrol 'QUERYSTATE', 'SQLServerAgent'
  5740.                     if exists (select * from #sqlstatus where status='Running.') 
  5741.                             exec @stopcode = msdb.dbo.sp_stop_job @job_id = @job_id
  5742.                                  if @@ERROR<>0 GOTO UNDO
  5743.                     drop table #sqlstatus   
  5744.                     if @stopcode=0 
  5745.                         waitfor delay '00:00:30'
  5746.                 end
  5747.             
  5748.             EXEC @retcode = msdb.dbo.sp_update_job @job_id=@job_id, @delete_level=3 -- NOTE: Run once, success or failure!
  5749.             IF @@ERROR <> 0 or @retcode <> 0
  5750.                 GOTO UNDO
  5751.         
  5752.             EXEC @retcode = msdb.dbo.sp_delete_jobstep @job_id=@job_id, @step_id=3
  5753.             IF @@ERROR <> 0 or @retcode <> 0
  5754.                 GOTO UNDO
  5755.             EXEC @retcode = msdb.dbo.sp_delete_jobstep @job_id=@job_id, @step_id=1
  5756.             IF @@ERROR <> 0 or @retcode <> 0
  5757.                 GOTO UNDO
  5758.  
  5759.             select @job_command=command from msdb.dbo.sysjobsteps where job_id=@job_id and step_id=1        
  5760.             select @job_command = @job_command + ' -UnSubscribe 0 '  -- currently the value does not really matter
  5761.             
  5762.             EXEC @retcode = msdb.dbo.sp_update_jobstep @job_id=@job_id, @step_id=1, 
  5763.                                 @on_success_action=1, 
  5764.                                 @on_fail_action=2, 
  5765.                                 @command=@job_command
  5766.             IF @@ERROR <> 0 or @retcode <> 0
  5767.                 GOTO UNDO
  5768.  
  5769.             
  5770.             select @schedule_name = formatmessage(20532)
  5771.             EXEC @retcode = msdb.dbo.sp_update_jobschedule @job_id=@job_id, @name=@schedule_name, @freq_subday_type = 2, @freq_subday_interval=30
  5772.             IF @@ERROR<>0 or @retcode<>0
  5773.                 GOTO UNDO
  5774.             
  5775.             if (@is_continuous  = 1) and (@stopcode = 0)
  5776.                 begin
  5777.                     EXEC @retcode = msdb.dbo.sp_start_job @job_id=@job_id
  5778.                      if @@ERROR<>0 
  5779.                         GOTO UNDO
  5780.                 end
  5781.             /*
  5782.             ** The last run of this job will be as scheduled
  5783.             */
  5784.     END
  5785.  
  5786.     -- Remove agent entry
  5787.     DELETE MSdistribution_agents WHERE id = @agent_id
  5788.     IF @@ERROR <> 0 
  5789.         GOTO UNDO
  5790.  
  5791.     -- Remove associated history 
  5792.     DELETE MSdistribution_history WHERE agent_id = @agent_id
  5793.     IF @@ERROR <> 0 
  5794.         GOTO UNDO
  5795.  
  5796.     -- Update global replication status table
  5797.     EXEC dbo.sp_MSupdate_replication_status
  5798.         @publisher,
  5799.         @publisher_db,
  5800.         @publication,
  5801.         @agent_type = 3,
  5802.         @agent_name = @name,
  5803.         @status = -1    -- delete status
  5804.  
  5805.     COMMIT TRAN
  5806.  
  5807.     RETURN(0)
  5808.  
  5809. UNDO:
  5810.     if @@TRANCOUNT = 1
  5811.         ROLLBACK TRAN
  5812.     else
  5813.         COMMIT TRAN
  5814.     return(1)
  5815. END
  5816. GO
  5817.  
  5818. raiserror(15339,-1,-1,'sp_MSdrop_distribution_agentid')
  5819. GO
  5820. CREATE PROCEDURE sp_MSdrop_distribution_agentid (
  5821.     @agent_id int
  5822. ) AS
  5823.  
  5824.  
  5825.     SET NOCOUNT ON
  5826.  
  5827.     /*
  5828.     ** Declarations.
  5829.     */
  5830.     DECLARE @name           nvarchar(100)
  5831.     DECLARE @publisher      sysname
  5832.     DECLARE @publisher_db   sysname
  5833.     DECLARE @publication    sysname
  5834.  
  5835.     SELECT @name = name, @publisher = srvname, @publisher_db = publisher_db, @publication = publication FROM 
  5836.         MSdistribution_agents, master..sysservers WHERE 
  5837.         id = @agent_id and
  5838.         srvid = publisher_id
  5839.     
  5840.     -- Delete Perfmon instance
  5841.     dbcc deleteinstance ("SQL Replication Distribution", @name)
  5842.  
  5843.     -- Mask agent type, do this before deletion of the row
  5844.     declare @agent_type int
  5845.     set @agent_type = dbo.fn_MSmask_agent_type (@agent_id, 3)
  5846.  
  5847.     -- Remove agent entry
  5848.     DELETE MSdistribution_agents WHERE id = @agent_id
  5849.     IF @@ERROR <> 0 
  5850.         return 1
  5851.  
  5852.  
  5853.     -- Update global replication status table
  5854.     EXEC dbo.sp_MSupdate_replication_status
  5855.         @publisher,
  5856.         @publisher_db,
  5857.         @publication,
  5858.         @publication_type = 1,
  5859.         @agent_type = @agent_type,
  5860.         @agent_name = @name,
  5861.         @status = -1    -- delete status
  5862.  
  5863.     return 0
  5864.  
  5865. GO
  5866.  
  5867. raiserror(15339,-1,-1,'sp_MSdrop_qreader_agent')
  5868. GO
  5869. CREATE PROCEDURE sp_MSdrop_qreader_agent (
  5870.     @agent_id int
  5871. ) AS
  5872. BEGIN
  5873.     SET NOCOUNT ON
  5874.     --
  5875.     -- Declarations.
  5876.     --
  5877.     DECLARE @retcode        int
  5878.     DECLARE @job_id         binary(16)
  5879.     DECLARE @name           nvarchar(100)
  5880.     DECLARE @database        sysname
  5881.  
  5882.     select @database = db_name()
  5883.  
  5884.     -- get the agent and job ids
  5885.     SELECT @job_id = job_id, @name = name
  5886.     FROM MSqreader_agents 
  5887.     WHERE id = @agent_id        
  5888.  
  5889.     if (@agent_id is NULL)
  5890.         return (0)
  5891.                     
  5892.     -- Delete Perfmon instance
  5893.     dbcc deleteinstance ('SQL Replication QueueReader', @name)
  5894.  
  5895.     BEGIN TRAN sp_MSdrop_qreader_agent
  5896.  
  5897.     -- delete job for the agent
  5898.     IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  5899.     BEGIN
  5900.         EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  5901.         IF (@@ERROR != 0 or @retcode != 0)
  5902.             GOTO UNDO
  5903.     END
  5904.  
  5905.     -- Remove agent entry
  5906.     DELETE MSqreader_agents WHERE id = @agent_id        
  5907.     IF (@@ERROR != 0)
  5908.         GOTO UNDO
  5909.  
  5910.     -- Remove associated history 
  5911.     DELETE MSqreader_history 
  5912.     WHERE agent_id = @agent_id 
  5913.     IF (@@ERROR != 0)
  5914.         GOTO UNDO
  5915.  
  5916.     -- Update global replication status table
  5917.     EXEC dbo.sp_MSupdate_replication_status
  5918.         @@servername,
  5919.         @database,
  5920.         'ALL',
  5921.         @agent_type = 9,
  5922.         @agent_name = @name,
  5923.         @status = -1    -- delete status
  5924.  
  5925.     COMMIT TRAN sp_MSdrop_qreader_agent
  5926.     RETURN(0)
  5927.  
  5928. UNDO:
  5929.     ROLLBACK TRAN sp_MSdrop_qreader_agent
  5930.     return(1)
  5931. END
  5932. GO
  5933.  
  5934. raiserror(15339,-1,-1,'sp_MSdrop_qreader_history')
  5935. GO
  5936. CREATE PROCEDURE sp_MSdrop_qreader_history (
  5937.     @publication_id int
  5938. ) AS
  5939. BEGIN
  5940.     SET NOCOUNT ON
  5941.  
  5942.     -- Remove associated history 
  5943.     DELETE MSqreader_history 
  5944.     WHERE publication_id = @publication_id 
  5945.     IF (@@ERROR != 0)
  5946.         return (1)
  5947.     else
  5948.         return 0
  5949. END
  5950. GO
  5951.  
  5952. raiserror(15339,-1,-1,'sp_MSdrop_merge_agentid')
  5953. GO
  5954. CREATE PROCEDURE sp_MSdrop_merge_agentid (
  5955.     @agent_id int
  5956. ) AS
  5957.  
  5958.  
  5959.     SET NOCOUNT ON
  5960.  
  5961.     /*
  5962.     ** Declarations.
  5963.     */
  5964.     DECLARE @name           nvarchar(100)
  5965.     DECLARE @publisher      sysname
  5966.     DECLARE @publisher_db   sysname
  5967.     DECLARE @publication    sysname
  5968.  
  5969.     SELECT @name = name, @publisher = srvname, @publisher_db = publisher_db, @publication = publication FROM 
  5970.         MSmerge_agents, master..sysservers WHERE 
  5971.         id = @agent_id and
  5972.         srvid = publisher_id
  5973.     
  5974.     -- Delete Perfmon instance
  5975.     dbcc deleteinstance ("SQL Replication Merge", @name)
  5976.  
  5977.     -- Mask agent type, do this before delete the row.
  5978.     declare @agent_type int
  5979.     set @agent_type = dbo.fn_MSmask_agent_type (@agent_id, 4)
  5980.  
  5981.     -- Remove agent entry
  5982.     DELETE MSmerge_agents WHERE id = @agent_id
  5983.     IF @@ERROR <> 0 
  5984.         return 1
  5985.  
  5986.  
  5987.     -- Update global replication status table
  5988.     EXEC dbo.sp_MSupdate_replication_status
  5989.         @publisher,
  5990.         @publisher_db,
  5991.         @publication,
  5992.         @agent_type = @agent_type,
  5993.         @agent_name = @name,
  5994.         @status = -1    -- delete status
  5995.  
  5996.     return 0
  5997.  
  5998. GO
  5999.  
  6000. raiserror(15339,-1,-1,'sp_MSadd_qreader_agent')
  6001. GO
  6002. CREATE PROCEDURE sp_MSadd_qreader_agent (
  6003.     @name nvarchar(100) = NULL,
  6004.     @agent_id int = NULL OUTPUT,
  6005.     @agent_jobid binary(16) = NULL OUTPUT) 
  6006. AS
  6007. BEGIN
  6008.     SET NOCOUNT ON
  6009.  
  6010.     DECLARE @retcode                int
  6011.             ,@profile_id            int
  6012.             ,@category_name            sysname
  6013.             ,@database                sysname
  6014.  
  6015.     -- these are defaults used for sp_MSadd_repl_job
  6016.             ,@frequency_type int,
  6017.             @frequency_interval int,
  6018.             @frequency_relative_interval int,
  6019.             @frequency_recurrence_factor int,
  6020.             @frequency_subday int,
  6021.             @frequency_subday_interval int,
  6022.             @active_start_time_of_day int,
  6023.             @active_end_time_of_day int,
  6024.             @active_start_date int,
  6025.             @active_end_date int,
  6026.             @retryattempts int,
  6027.             @retrydelay int,
  6028.             @command nvarchar(4000)
  6029.             ,@jobname sysname
  6030.             ,@agent_name nvarchar(100)
  6031.  
  6032.     SELECT
  6033.         @frequency_type = 64,
  6034.         @frequency_interval = 1,
  6035.         @frequency_relative_interval = 1,
  6036.         @frequency_recurrence_factor  = 0,
  6037.         @frequency_subday = 4,
  6038.         @frequency_subday_interval = 5,
  6039.         @active_start_time_of_day = 0,
  6040.         @active_end_time_of_day = 235959,
  6041.         @active_start_date = 0,
  6042.         @active_end_date = 99991231,
  6043.         @retryattempts = 10,
  6044.         @retrydelay = 1
  6045.  
  6046.     --
  6047.     -- initialize
  6048.     --
  6049.     select @database = db_name()
  6050.             ,@agent_id = NULL
  6051.             ,@agent_jobid = NULL
  6052.  
  6053.     --
  6054.     -- Check for Agent entry
  6055.     --
  6056.     select top 1 @agent_id = id, @agent_name = name
  6057.     from dbo.MSqreader_agents
  6058.  
  6059.     --
  6060.     -- Check if we have any queue reader jobs for this database
  6061.     --
  6062.     select @agent_jobid = job.job_id
  6063.             ,@jobname = job.name 
  6064.     from msdb..sysjobs as job join msdb..sysjobsteps as step 
  6065.         on job.job_id = step.job_id 
  6066.             and job.category_id = 19
  6067.             and UPPER(job.originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName')))
  6068.             and step.subsystem = N'QueueReader' 
  6069.             and step.database_name = @database
  6070.  
  6071.     --
  6072.     -- begin tran
  6073.     --
  6074.     BEGIN TRAN sp_MSadd_qreader_agent
  6075.     
  6076.     --
  6077.     -- Check if we need to proceed
  6078.     -- add agent entry and job entry as required
  6079.     --
  6080.     if ((@agent_id IS NOT NULL) and (@agent_jobid IS NOT NULL))
  6081.     begin
  6082.         --
  6083.         -- we have an entry in MSqreader_agents and an entry in 
  6084.         -- msdb..sysjobs, make sure the names and jobid match
  6085.         --
  6086.         if (@agent_name != @jobname)
  6087.         begin
  6088.             --
  6089.             -- Update the agent name to be same as the job name
  6090.             --
  6091.             UPDATE MSqreader_agents SET name = @jobname WHERE id = @agent_id
  6092.             IF (@@ERROR != 0)
  6093.                 GOTO UNDO
  6094.         end
  6095.  
  6096.         if not exists (select * from MSqreader_agents
  6097.             where id = @agent_id and job_id = @agent_jobid)
  6098.         begin
  6099.             --
  6100.             -- Update the agent job_id if necessary
  6101.             --
  6102.             UPDATE MSqreader_agents SET job_id = @agent_jobid WHERE id = @agent_id
  6103.             IF (@@ERROR != 0)
  6104.                 GOTO UNDO
  6105.         end
  6106.  
  6107.         COMMIT TRAN sp_MSadd_qreader_agent
  6108.         RETURN(0)
  6109.     end
  6110.  
  6111.     --
  6112.     -- prepare the command
  6113.     -- Since this will always run on NT, use integrated security
  6114.     --
  6115.     select @command = N'-Distributor ' + quotename(@@SERVERNAME) 
  6116.                     + N' -DistributionDB ' + quotename(@database) 
  6117.                     + N' -DistributorSecurityMode 1 '
  6118.     
  6119.     SELECT @profile_id = profile_id
  6120.     FROM msdb..MSagent_profiles
  6121.     WHERE agent_type = 9
  6122.     AND def_profile = 1
  6123.  
  6124.     IF @profile_id IS NULL
  6125.         GOTO UNDO
  6126.  
  6127.     --
  6128.     -- Set the name
  6129.     --
  6130.     if (@name is NULL)
  6131.     begin
  6132.         select @name = case 
  6133.             when (@agent_name IS NULL and @jobname IS NULL) 
  6134.                 then quotename(@@servername) + '.' + cast(db_id() as nvarchar)
  6135.             when (@jobname IS NOT NULL)
  6136.                 then cast(@jobname as nvarchar(100))
  6137.                 else @agent_name
  6138.             end
  6139.     end
  6140.     else
  6141.     begin
  6142.         --
  6143.         -- we will override the user specified name if
  6144.         -- a job already exists
  6145.         --
  6146.         if (@jobname IS NOT NULL and @jobname != @name)
  6147.             select name = cast(@jobname as nvarchar(100))
  6148.     end
  6149.     
  6150.     --
  6151.     -- Insert row and Add Perfmoon instance only if needed
  6152.     --
  6153.     if (@agent_id IS NULL)
  6154.     begin
  6155.         INSERT INTO MSqreader_agents (name, profile_id) VALUES (@name, @profile_id)
  6156.         IF (@@ERROR != 0)
  6157.             GOTO UNDO
  6158.         SELECT @agent_id = @@IDENTITY
  6159.         dbcc addinstance ('SQL Replication QueueReader', @name)
  6160.     end
  6161.     else
  6162.     begin
  6163.         --
  6164.         -- update Agent name if necessary
  6165.         --
  6166.         if not exists (select * from MSqreader_agents 
  6167.             where id = @agent_id and name = @name) 
  6168.         begin
  6169.             UPDATE MSqreader_agents SET name = @name WHERE id = @agent_id
  6170.             IF (@@ERROR != 0)
  6171.                 GOTO UNDO
  6172.         end
  6173.     end
  6174.  
  6175.     --
  6176.     -- add the job if necessary
  6177.     -- For DMO scripting
  6178.     -- if the corresponding job for this agent does not exist we will 
  6179.     -- proceed and create the job (This is for the case when the user 
  6180.     -- generated the script at the publisher but did not re-create 
  6181.     -- repl jobs at the distributor.)
  6182.     --
  6183.     if (@agent_jobid IS NULL)
  6184.     begin
  6185.         -- Get Qreader category name (assumes category_id = 19)
  6186.         select @category_name = name FROM msdb.dbo.syscategories where category_id = 19
  6187.         
  6188.         EXECUTE @retcode = dbo.sp_MSadd_repl_job
  6189.             @name = @name,
  6190.             @subsystem = 'QueueReader',
  6191.             @server = @@SERVERNAME,
  6192.             @databasename = @database,
  6193.             @enabled = 1,
  6194.             @freqtype = @frequency_type,
  6195.             @freqinterval = @frequency_interval,
  6196.             @freqsubtype = @frequency_subday,
  6197.             @freqsubinterval = @frequency_subday_interval,
  6198.             @freqrelativeinterval = @frequency_relative_interval,
  6199.             @freqrecurrencefactor = 0,
  6200.             @activestartdate = @active_start_date,
  6201.             @activeenddate = @active_end_date,
  6202.             @activestarttimeofday = @active_start_time_of_day,
  6203.             @activeendtimeofday = @active_end_time_of_day,
  6204.             @nextrundate = 0,
  6205.             @nextruntime = 0,
  6206.             @runpriority = 0,
  6207.             @emailoperatorname = NULL,
  6208.             @retryattempts = @retryattempts,
  6209.             @retrydelay = @retrydelay,
  6210.             @command = @command,
  6211.             @loghistcompletionlevel = 0,
  6212.             @emailcompletionlevel = 0,
  6213.             @description = 'Reads queues for Queued updating subscriptions',
  6214.             @category_name = @category_name,
  6215.             @failure_detection = 1,
  6216.             @agent_id = @agent_id,
  6217.             @job_id = @agent_jobid OUTPUT
  6218.  
  6219.         IF (@@ERROR != 0 or @retcode != 0)
  6220.             GOTO UNDO
  6221.     end
  6222.     
  6223.     -- update agents table with the job id
  6224.     UPDATE MSqreader_agents SET job_id = @agent_jobid WHERE id = @agent_id
  6225.     IF (@@ERROR != 0)
  6226.         GOTO UNDO
  6227.  
  6228.     -- Update global replication status table
  6229.     EXEC @retcode = dbo.sp_MSupdate_replication_status
  6230.         @@servername,
  6231.         @database,
  6232.         'ALL',
  6233.         @agent_type = 9,
  6234.         @agent_name = @name,
  6235.         @status = 0     -- not running status
  6236.     IF (@@ERROR != 0 or @retcode != 0)
  6237.         GOTO UNDO
  6238.  
  6239.     COMMIT TRAN sp_MSadd_qreader_agent
  6240.     RETURN(0)
  6241.  
  6242. UNDO:
  6243.     --
  6244.     -- Since this proc is called from other SPs, doing
  6245.     -- a ROLLBACK can roll all the way to the top 
  6246.     -- so check for that and commit and return error code.
  6247.     -- the top level calling SP should do proper rollback
  6248.     -- based on returned error code
  6249.     --
  6250.     if (@@TRANCOUNT = 1)
  6251.         ROLLBACK TRAN sp_MSadd_qreader_agent
  6252.     else
  6253.         COMMIT TRAN sp_MSadd_qreader_agent
  6254.     return(1)
  6255. END
  6256. GO
  6257.  
  6258. raiserror(15339,-1,-1,'sp_MSadd_distribution_agent')
  6259. GO
  6260. CREATE PROCEDURE sp_MSadd_distribution_agent (
  6261.     @name sysname = NULL,
  6262.     @publisher_id smallint,
  6263.     @publisher_db sysname,
  6264.     @publication sysname,  
  6265.     @subscriber_id smallint,
  6266.     @subscriber_db sysname,
  6267.     @subscription_type int, -- have to have it to identify a distribution agent.
  6268.     @local_job bit, 
  6269.  
  6270.     @frequency_type int = 64,
  6271.     @frequency_interval int = 1,
  6272.     @frequency_relative_interval int = 1,
  6273.     @frequency_recurrence_factor int = 0,
  6274.     @frequency_subday int = 4,
  6275.     @frequency_subday_interval int = 5,
  6276.     @active_start_time_of_day int = 0,
  6277.     @active_end_time_of_day int = 235959,
  6278.     @active_start_date int = 0,
  6279.     @active_end_date int = 99991231,
  6280.  
  6281.     @retryattempts int = 10,
  6282.     @retrydelay int = 1,
  6283.     
  6284.     @command nvarchar(4000) = NULL,
  6285.     @agent_id int = NULL OUTPUT,
  6286.     @distribution_jobid binary(16) = NULL OUTPUT,
  6287.     @update_mode int = 0, 
  6288.  
  6289.     -- Agent offload
  6290.     @offloadagent bit = 0,
  6291.     @offloadserver sysname = NULL,
  6292.  
  6293.     @dts_package_name sysname = NULL,
  6294.     @dts_package_password nvarchar(524) = NULL,
  6295.     @dts_package_location int = 0
  6296. AS
  6297. BEGIN
  6298.     
  6299.     SET NOCOUNT ON
  6300.  
  6301.     /*
  6302.     ** Declarations.
  6303.     */
  6304.     DECLARE @retcode            int
  6305.         ,@database           sysname
  6306.         ,@profile_id         int
  6307.         ,@distribution_type  int
  6308.         ,@publisher          sysname
  6309.         ,@category_name      sysname
  6310.         ,@subscriber         sysname
  6311.         ,@publisher_database_id int
  6312.         ,@queue_id             sysname
  6313.         ,@qservicestatus    int
  6314.         ,@tries                tinyint
  6315.         ,@queue_server        sysname
  6316.  
  6317.     /*
  6318.     ** Initializations
  6319.     */
  6320.     select @database = DB_NAME()
  6321.     
  6322.     -- Check the existance of the package if it is at the distributor side.
  6323.     if @dts_package_name is not null and @dts_package_location = 0
  6324.     begin
  6325.         exec @retcode = dbo.sp_MSrepl_validate_dts_package
  6326.             @name = @dts_package_name
  6327.         IF @@ERROR <> 0 or @retcode <> 0
  6328.             return (1)
  6329.     end
  6330.  
  6331.     -- if @name is not null, the proc is from DMO scripting
  6332.     -- check to see if the job is there or not, if not, reset @job_existing and
  6333.     -- @name values. This is for the case when the user generate the script at
  6334.     -- the publisher but did not re-create repl jobs at the distributor.
  6335.     if @local_job = 1 and @name is not null and 
  6336.        @name <> N''
  6337.     begin
  6338.         if not exists (select * from msdb..sysjobs_view where 
  6339.             name = @name and
  6340.             UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName'))))
  6341.         begin
  6342.             set @name = null
  6343.         end
  6344.     end
  6345.  
  6346.     BEGIN TRAN
  6347.  
  6348.     -- Try to drop it first
  6349.     EXEC @retcode = dbo.sp_MSdrop_distribution_agent 
  6350.         @publisher_id = @publisher_id,
  6351.         @publisher_db = @publisher_db,
  6352.         @publication = @publication,
  6353.         @subscriber_id = @subscriber_id,
  6354.         @subscriber_db = @subscriber_db,
  6355.         @subscription_type = @subscription_type
  6356.     IF @@ERROR <> 0 or @retcode <> 0
  6357.         GOTO UNDO
  6358.  
  6359.     /* Code for distribution agent type in MSagent_profiles */
  6360.     SELECT @distribution_type = 3
  6361.  
  6362.     SELECT @profile_id = profile_id
  6363.     FROM msdb..MSagent_profiles
  6364.     WHERE agent_type = @distribution_type
  6365.         AND def_profile = 1
  6366.  
  6367.     IF @profile_id IS NULL
  6368.         GOTO UNDO
  6369.  
  6370.     select @publisher = srvname from master..sysservers where srvid = @publisher_id
  6371.     select @subscriber = srvname from master..sysservers where srvid = @subscriber_id
  6372.     select @publisher_database_id = id from MSpublisher_databases where 
  6373.         publisher_id = @publisher_id and
  6374.         publisher_db = @publisher_db
  6375.  
  6376.     -- Create queue if needed. (queued or failover mode)
  6377.     if (@update_mode in (2,3))
  6378.     begin
  6379.         --
  6380.         -- Check if the MSMQ service is running
  6381.         -- BYPASS the check for clusters
  6382.         --
  6383.         if ( SERVERPROPERTY('IsClustered') = 0 )
  6384.         begin
  6385.             exec @retcode = master.dbo.xp_controlqueueservice 
  6386.                                 @control_command = 1,
  6387.                                 @return_result = @qservicestatus output
  6388.             if (@retcode != 0 or @@error != 0)
  6389.             begin
  6390.                 raiserror('sp_MSadd_distribution_agent(debug): xp_controlqueueservice failed in check mode', 16, 1)
  6391.                 GOTO UNDO
  6392.             end
  6393.  
  6394.             if (@qservicestatus != 1)
  6395.             begin
  6396.                 raiserror('sp_MSadd_distribution_agent(debug): MSMQ service not running. Start MSMQ services and retry subscription creation', 16, 1)
  6397.                 GOTO UNDO
  6398.             end
  6399.  
  6400.             /***************************************************
  6401.             ***** For NOW we will not AUTOSTART MSMQ services
  6402.             ****************************************************
  6403.             if (@qservicestatus != 1)
  6404.             begin
  6405.                 -- Queue service is not running. Try starting it only if it is
  6406.                 -- stopped. Otherwise, return with error (we do not want to 
  6407.                 -- handle the cases for Pause/Pending/Continue states)
  6408.                 if (@qservicestatus = 2)
  6409.                 begin
  6410.                     -- start the service
  6411.                     exec @retcode = master.dbo.xp_controlqueueservice 
  6412.                                         @control_command = 2,
  6413.                                         @return_result = @qservicestatus output
  6414.                     if (@retcode != 0 or @@error != 0)
  6415.                     begin
  6416.                         raiserror('sp_MSadd_distribution_agent(debug): xp_controlqueueservice failed in start mode', 16, 1)
  6417.                         GOTO UNDO
  6418.                     end
  6419.  
  6420.                     -- check status (try 3 times with 2 sec delays)
  6421.                     select @tries = 0
  6422.                     while ((@qservicestatus != 1) and (@tries < 3))
  6423.                     begin
  6424.                         WAITFOR DELAY '00:00:02'
  6425.                         select @tries = @tries + 1
  6426.                         
  6427.                         exec @retcode = master.dbo.xp_controlqueueservice 
  6428.                                             @control_command = 1,
  6429.                                             @return_result = @qservicestatus output
  6430.                         if (@retcode != 0 or @@error != 0)
  6431.                         begin
  6432.                             raiserror('sp_MSadd_distribution_agent(debug): xp_controlqueueservice failed in check mode', 16, 1)
  6433.                             GOTO UNDO
  6434.                         end                    
  6435.                     end
  6436.  
  6437.                     -- Did the service start
  6438.                     if (@qservicestatus != 1)
  6439.                     begin
  6440.                         raiserror('sp_MSadd_distribution_agent(debug): MSMQ service not running (delayed)', 16, 1)
  6441.                         GOTO UNDO
  6442.                     end
  6443.                 end
  6444.                 else
  6445.                 begin
  6446.                     raiserror('sp_MSadd_distribution_agent(debug): MSMQ service not running (in transient state)', 16, 1)
  6447.                     GOTO UNDO
  6448.                 end
  6449.             end
  6450.             ***************************************************/
  6451.         end
  6452.  
  6453.         --
  6454.         -- create local private queue
  6455.         --
  6456.         select @queue_id = cast(NEWID() as sysname)
  6457.         select @queue_server = @queue_id
  6458.         exec @retcode = master.dbo.xp_createprivatequeue @queue_server OUTPUT
  6459.         IF @@ERROR != 0 or @retcode != 0
  6460.         BEGIN
  6461.             select @queue_id = NULL
  6462.                     ,@queue_server = NULL
  6463.             RAISERROR('Debug: xp_createprivatequeue failed', -1, -1) WITH NOWAIT
  6464.             GOTO UNDO
  6465.         END
  6466.     end
  6467.     else if (@update_mode in (4,5))
  6468.     begin
  6469.         --
  6470.         -- SQL Queue being used
  6471.         --
  6472.         select @queue_id = N'mssqlqueue'
  6473.     end
  6474.  
  6475.     
  6476.     /* 
  6477.     ** Insert row
  6478.     */
  6479.     INSERT INTO MSdistribution_agents (name, publisher_database_id, publisher_id, publisher_db, publication, 
  6480.             subscriber_id, subscriber_db, subscription_type, local_job, 
  6481.             subscription_guid, profile_id, queue_id, queue_server,
  6482.             dts_package_name, dts_package_password, dts_package_location)
  6483.         VALUES ('',@publisher_database_id, @publisher_id, @publisher_db, @publication, 
  6484.             @subscriber_id, @subscriber_db, @subscription_type, @local_job, 
  6485.             newid(), @profile_id, @queue_id, @queue_server,
  6486.             @dts_package_name, @dts_package_password, @dts_package_location)
  6487.     IF @@ERROR <> 0
  6488.         GOTO UNDO
  6489.     
  6490.     SELECT @agent_id = @@IDENTITY
  6491.  
  6492.     -- Add Perfmoon instance
  6493.     dbcc addinstance ("SQL Replication Distribution", @name)
  6494.  
  6495.     -- Set agent name
  6496.     if @subscriber is NULL select @subscriber = ''
  6497.     if @subscriber_db is NULL select @subscriber_db =''
  6498.     
  6499.     declare @job_existing bit
  6500.     
  6501.     IF @name IS NULL OR @name = N''
  6502.     BEGIN
  6503.         /*
  6504.         ** Sacrifice 1-2 character from each of (@publisher,@publication,
  6505.         ** @publisher_db,subscriber) to allow 4 more indentity digits in
  6506.         ** the distribution agent name. This will hopefully provide better
  6507.         ** guarantee of agent name uniqueness.
  6508.         */
  6509.         if @publication is NOT NULL and (LOWER(@publication)<>'all')
  6510.             SELECT @name = CONVERT(nvarchar(21),@publisher ) + '-' + 
  6511.                 CONVERT(nvarchar(21),@publisher_db) + '-' + 
  6512.                 CONVERT(nvarchar(21),@publication) + '-' + 
  6513.                 CONVERT(nvarchar(21),@subscriber) + '-' +
  6514.                 CONVERT(nvarchar, @@IDENTITY)
  6515.         else
  6516.             SELECT @name = CONVERT(nvarchar(28),@publisher ) + '-' + 
  6517.                 CONVERT(nvarchar(28),@publisher_db) + '-' + 
  6518.                 CONVERT(nvarchar(28),@subscriber) + '-' + 
  6519.                 CONVERT(nvarchar, @@IDENTITY)
  6520.  
  6521.         select @job_existing = 0
  6522.     END
  6523.     else
  6524.         select @job_existing = 1
  6525.  
  6526.     -- If creating a new job and the generated name already exists, re-generate the name with a 
  6527.     -- guid appended
  6528.     IF  @job_existing = 0
  6529.     BEGIN
  6530.         IF EXISTS (SELECT * FROM msdb..sysjobs_view 
  6531.                     WHERE name = @name 
  6532.                       AND UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName'))))
  6533.         BEGIN
  6534.             if @publication is NOT NULL and (LOWER(@publication)<>'all')
  6535.                 SELECT @name = fn_repluniquename(newid(), @publisher, @publisher_db, 
  6536.                     @publication, @subscriber)
  6537.             else
  6538.                 SELECT @name = fn_repluniquename(newid(), @publisher, @publisher_db, 
  6539.                     @subscriber, null)
  6540.         END            
  6541.     END
  6542.  
  6543.     IF @local_job = 1
  6544.     BEGIN
  6545.         if @job_existing = 0
  6546.         begin
  6547.     --    *******WORKAROUND*******
  6548.             DECLARE @nullchar nchar(20)
  6549.             SELECT @nullchar = NULL
  6550.     --    *******WORKAROUND*******
  6551.             -- Get Distribution category name (assumes category_id = 10)
  6552.             select @category_name = name FROM msdb.dbo.syscategories where category_id = 10
  6553.  
  6554.             if @frequency_recurrence_factor is null
  6555.                 select @frequency_recurrence_factor = 0
  6556.  
  6557.             EXECUTE @retcode = dbo.sp_MSadd_repl_job
  6558.             @name = @name,
  6559.             @subsystem = 'Distribution',
  6560.             @server = @@SERVERNAME,
  6561.             @databasename = @database,
  6562.             @enabled = 1,
  6563.             @freqtype = @frequency_type,
  6564.             @freqinterval = @frequency_interval,
  6565.             @freqsubtype = @frequency_subday,
  6566.             @freqsubinterval = @frequency_subday_interval,
  6567.             @freqrelativeinterval = @frequency_relative_interval,
  6568.             @freqrecurrencefactor = @frequency_recurrence_factor,
  6569.             @activestartdate = @active_start_date,
  6570.             @activeenddate = @active_end_date,
  6571.             @activestarttimeofday = @active_start_time_of_day,
  6572.             @activeendtimeofday = @active_end_time_of_day,
  6573.             @nextrundate = 0,
  6574.             @nextruntime = 0,
  6575.             @runpriority = 0,
  6576.             @emailoperatorname = NULL,
  6577.             @retryattempts = @retryattempts,
  6578.             @retrydelay = @retrydelay,
  6579.             @command = @command,
  6580.             @loghistcompletionlevel = 0,
  6581.             @emailcompletionlevel = 0,
  6582.             @description = NULL,
  6583.             @category_name = @category_name,
  6584.             @failure_detection = 1,
  6585.             @agent_id = @agent_id,
  6586.             @job_id = @distribution_jobid OUTPUT
  6587.  
  6588.            IF @@ERROR <> 0 or @retcode <> 0
  6589.                 GOTO UNDO
  6590.         end
  6591.         else
  6592.         begin
  6593.             select @distribution_jobid = job_id from msdb..sysjobs_view where 
  6594.                 name = @name and
  6595.                 UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName')))
  6596.             if @distribution_jobid IS NULL
  6597.             begin
  6598.                 -- Message from msdb.dbo.sp_verify_job_identifiers
  6599.                 RAISERROR(14262, -1, -1, 'Job', @name)          
  6600.                 GOTO UNDO
  6601.             end
  6602.         end
  6603.     END
  6604.     ELSE 
  6605.     BEGIN
  6606.         -- Generate a job GUID for remote agents. This will be used by the UI to uniquely
  6607.         -- identify rows returned by the enums
  6608.         set @distribution_jobid = newid();
  6609.     END
  6610.  
  6611.     UPDATE MSdistribution_agents SET name = @name,
  6612.         job_id = @distribution_jobid WHERE
  6613.         id = @agent_id
  6614.  
  6615.     IF @@ERROR <> 0
  6616.         GOTO UNDO
  6617.  
  6618.     -- Don't call agent offload stuff for virtual agents.
  6619.     IF @local_job = 1 and @subscription_type = 0
  6620.     BEGIN    
  6621.         -- Add offload parameter to agent command line if necessary
  6622.         IF @offloadagent = 1 
  6623.         BEGIN
  6624.             EXEC @retcode = sp_MSenableagentoffload @job_id = @distribution_jobid,
  6625.                                            @offloadserver = @offloadserver
  6626.         END
  6627.         ELSE
  6628.         BEGIN
  6629.             EXEC @retcode = sp_MSdisableagentoffload @job_id = @distribution_jobid,
  6630.                                             @offloadserver = @offloadserver
  6631.         END
  6632.         IF @@ERROR <> 0 OR @retcode <> 0
  6633.             GOTO UNDO
  6634.  
  6635.     END
  6636.  
  6637.     -- Update global replication status table
  6638.     EXEC @retcode = dbo.sp_MSupdate_replication_status
  6639.         @publisher,
  6640.         @publisher_db,
  6641.         @publication,
  6642.         @agent_type = 3,
  6643.         @agent_name = @name,
  6644.         @status = 0     -- not running status
  6645.  
  6646.     IF @@ERROR <> 0 OR @retcode <> 0
  6647.         GOTO UNDO
  6648.  
  6649.     COMMIT TRAN
  6650.  
  6651.     RETURN(0)
  6652. UNDO:
  6653.     --
  6654.     -- delete the MSMQ queue if necessary
  6655.     --
  6656.     if (@update_mode in (2,3) and @queue_server IS NOT NULL and @queue_id IS NOT NULL)
  6657.     begin
  6658.         exec master.dbo.xp_deleteprivatequeue @queue_server, @queue_id
  6659.     end
  6660.     
  6661.     if @@TRANCOUNT = 1
  6662.         ROLLBACK TRAN
  6663.     else
  6664.         COMMIT TRAN
  6665.     return(1)
  6666. END
  6667. GO
  6668.  
  6669. raiserror(15339,-1,-1,'sp_MSdrop_agent_entry')
  6670. GO
  6671. /*
  6672. ** This one is reserved for future use.
  6673. */
  6674. CREATE PROCEDURE sp_MSdrop_agent_entry (
  6675. @pub_srvid      smallint,
  6676. @pub_db_name    sysname,
  6677. @publication    sysname,
  6678. @sub_srvid      smallint,
  6679. @sub_db_name    sysname
  6680. ) AS
  6681. delete from MSmerge_agents where publisher_id = @pub_srvid AND publisher_db = @pub_db_name AND publication=@publication
  6682.                                     AND subscriber_id = @sub_srvid AND subscriber_db = @sub_db_name
  6683. if @@ERROR<>0 return (1)
  6684. return (0)
  6685. GO
  6686.  
  6687.  
  6688. raiserror(15339,-1,-1,'sp_MSdrop_merge_agent')
  6689. GO
  6690. CREATE PROCEDURE sp_MSdrop_merge_agent (
  6691.     @publisher          sysname,
  6692.     @publisher_db       sysname,
  6693.     @publication        sysname,
  6694.     @subscriber         sysname,
  6695.     @subscriber_db      sysname,
  6696.     @keep_for_last_run  bit = 0 -- if the agent needs to stay to run one more time; default is NO
  6697. ) AS
  6698.  
  6699.  
  6700.     SET NOCOUNT ON
  6701.  
  6702.     /*
  6703.     ** Declarations.
  6704.     */
  6705.     DECLARE @retcode    int
  6706.     DECLARE @job_id     binary(16)
  6707.     DECLARE @local_job  bit
  6708.     DECLARE @publisher_id smallint
  6709.     DECLARE @subscriber_id smallint
  6710.     DECLARE @job_command nvarchar(512)
  6711.     DECLARE @name nvarchar(100)
  6712.     DECLARE @agent_id   int
  6713.  
  6714.     /*
  6715.     ** Initializations
  6716.     */
  6717.     -- Get subscriber info
  6718.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  6719.     select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  6720.  
  6721.  
  6722.     SELECT @job_id = job_id, @local_job = local_job, @name = name, @agent_id = id FROM MSmerge_agents (updlock holdlock) 
  6723.     WHERE
  6724.         publisher_id = @publisher_id AND
  6725.         publisher_db = @publisher_db AND
  6726.         publication = @publication and
  6727.         subscriber_id = @subscriber_id and
  6728.         subscriber_db = @subscriber_db 
  6729.  
  6730.     -- Delete Perfmon instance
  6731.     dbcc deleteinstance ("SQL Replication Merge", @name)
  6732.  
  6733.     -- Return if not exists
  6734.     IF @local_job IS NULL
  6735.         RETURN(0)
  6736.  
  6737.     BEGIN TRAN
  6738.  
  6739.     IF @keep_for_last_run = 0
  6740.     BEGIN
  6741.         if @local_job=1
  6742.         begin
  6743.             IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  6744.             begin
  6745.                 EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  6746.                 IF @@ERROR <> 0 or @retcode <> 0
  6747.                     GOTO UNDO
  6748.             end
  6749.         end
  6750.     END
  6751.  
  6752.     IF @local_job = 1 and @keep_for_last_run = 1
  6753.     BEGIN
  6754.         IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  6755.         BEGIN
  6756.             EXEC @retcode = msdb.dbo.sp_update_job @job_id=@job_id, @delete_level=3 -- NOTE: Only once, success or failure!
  6757.             IF @@ERROR <> 0 or @retcode <> 0
  6758.                 GOTO UNDO
  6759.             EXEC @retcode = msdb.dbo.sp_delete_jobstep @job_id=@job_id, @step_id=3
  6760.             IF @@ERROR <> 0 or @retcode <> 0
  6761.                 GOTO UNDO
  6762.             EXEC @retcode = msdb.dbo.sp_delete_jobstep @job_id=@job_id, @step_id=1
  6763.             IF @@ERROR <> 0 or @retcode <> 0
  6764.                 GOTO UNDO
  6765.  
  6766.             select @job_command=command from msdb.dbo.sysjobsteps where job_id=@job_id and step_id=1        
  6767.             select @job_command = @job_command + ' -AgentType 4 '
  6768.             
  6769.             EXEC @retcode = msdb.dbo.sp_update_jobstep @job_id=@job_id, @step_id=1, 
  6770.                 @on_success_action = 1,
  6771.                 @on_fail_action = 2,
  6772.                 @command=@job_command
  6773.             IF @@ERROR <> 0 or @retcode <> 0
  6774.                 GOTO UNDO
  6775.         END
  6776.     END
  6777.  
  6778.     DELETE MSmerge_agents WHERE id = @agent_id
  6779.     IF @@ERROR <> 0 
  6780.         GOTO UNDO
  6781.  
  6782.     -- Remove history       
  6783.     DELETE MSmerge_history WHERE agent_id = @agent_id 
  6784.     IF @@ERROR <> 0 
  6785.         GOTO UNDO
  6786.  
  6787.     -- Update global replication status table
  6788.     EXEC dbo.sp_MSupdate_replication_status
  6789.         @publisher,
  6790.         @publisher_db,
  6791.         @publication,
  6792.         @agent_type = 4,
  6793.         @agent_name = @name,
  6794.         @status = -1    -- delete status 
  6795.  
  6796.     COMMIT TRAN
  6797.  
  6798.     RETURN(0)
  6799.  
  6800. UNDO:
  6801.     if @@TRANCOUNT = 1
  6802.         ROLLBACK TRAN
  6803.     else
  6804.         COMMIT TRAN
  6805.     return(1)
  6806. GO
  6807.  
  6808. raiserror(15339,-1,-1,'sp_MSgetagentoffloadinfo')
  6809. GO
  6810. CREATE PROCEDURE sp_MSgetagentoffloadinfo (
  6811.     @job_id     VARBINARY(16)
  6812.     ) AS
  6813.  
  6814.     SET NOCOUNT ON
  6815.     DECLARE @agenttype NVARCHAR(20)
  6816.     DECLARE @offload_enabled bit
  6817.     DECLARE @offload_server  sysname
  6818.     DECLARE @agent_table     sysname  -- For use in error message
  6819.     DECLARE @independent_agent bit
  6820.  
  6821.     SELECT @agenttype = NULL
  6822.     SELECT @agent_table = RTRIM(@@SERVERNAME) + N'.dbo.'
  6823.     SELECT @independent_agent = 0
  6824.         
  6825.     SELECT @agenttype = LOWER(subsystem collate SQL_Latin1_General_CP1_CS_AS)
  6826.       FROM msdb..sysjobsteps
  6827.      WHERE job_id = @job_id
  6828.        AND LOWER(subsystem collate SQL_Latin1_General_CP1_CS_AS) IN (N'distribution', N'merge')
  6829.  
  6830.     IF @agenttype IS NULL
  6831.     BEGIN
  6832.         RAISERROR(21134, 16, -1)
  6833.         RETURN 1
  6834.     END
  6835.  
  6836.     IF @agenttype = N'distribution'
  6837.     BEGIN
  6838.         SELECT @offload_enabled = offload_enabled, 
  6839.                @offload_server = offload_server 
  6840.           FROM dbo.MSdistribution_agents da
  6841.     INNER JOIN dbo.MSsubscriptions s 
  6842.             ON da.id = s.agent_id
  6843.          WHERE job_id = @job_id        
  6844.         SELECT @agent_table = @agent_table + N'MSdistribution_agents'
  6845.     END
  6846.     ELSE
  6847.     BEGIN
  6848.         SELECT @offload_enabled = offload_enabled, 
  6849.                @offload_server = offload_server
  6850.           FROM dbo.MSmerge_agents
  6851.          WHERE job_id = @job_id 
  6852.         SELECT @agent_table = @agent_table + N'MSmerge_agents'
  6853.     END
  6854.  
  6855.     IF @@ROWCOUNT = 0
  6856.     BEGIN
  6857.         RAISERROR(21135, 16, -1, @agent_table)
  6858.         RETURN 1
  6859.     END
  6860.  
  6861.     IF @agenttype = N'distribution'
  6862.     BEGIN
  6863.         SELECT 'offload_enabled' = @offload_enabled,
  6864.                'offload_server' = @offload_server,
  6865.                'independent_agent' = @independent_agent
  6866.     END
  6867.     ELSE
  6868.     BEGIN
  6869.         SELECT 'offload_enabled' = @offload_enabled,
  6870.                'offload_server' = @offload_server
  6871.     END
  6872.  
  6873.     RETURN 0
  6874. GO
  6875.  
  6876. raiserror(15339,-1,-1,'sp_MSadd_merge_agent')
  6877. GO
  6878. CREATE PROCEDURE sp_MSadd_merge_agent (
  6879. -- not null if from scripting
  6880.     @name                           sysname = NULL,
  6881.     @publisher                      sysname,                    /* Publisher server */
  6882.     @publisher_db                   sysname,                    /* Publisher database */
  6883.     @publication                    sysname,                    /* Publication name */
  6884.     @subscriber                     sysname,                    /* Subscriber server */
  6885.     @subscriber_db                  sysname,                    /* Subscription database */
  6886.     @local_job                      bit,
  6887.     @frequency_type                 int = NULL,
  6888.     @frequency_interval             int = NULL,             
  6889.     @frequency_relative_interval    int = NULL, 
  6890.     @frequency_recurrence_factor    int = NULL, 
  6891.     @frequency_subday               int = NULL,
  6892.     @frequency_subday_interval      int = NULL,    
  6893.     @active_start_time_of_day       int = NULL, 
  6894.     @active_end_time_of_day         int = NULL,         
  6895.     @active_start_date              int = NULL, 
  6896.     @active_end_date                int = NULL,
  6897.     @optional_command_line          nvarchar(255) = '',     /* Optional command line arguments */
  6898.     @merge_jobid                    binary(16) = NULL OUTPUT,
  6899.     -- Agent offload
  6900.     @offloadagent                   bit = 0,
  6901.     @offloadserver                  sysname = NULL,
  6902.     @subscription_type              int = 0 -- 0 = push, 1 = pull
  6903.     ) AS
  6904.  
  6905.     SET NOCOUNT ON
  6906.  
  6907.     /*
  6908.     ** Declarations.
  6909.     */
  6910.     declare @retcode        int
  6911.     DECLARE @publisher_id   smallint
  6912.     DECLARE @subscriber_id  smallint
  6913.     DECLARE @profile_id     int
  6914.     DECLARE @merge_type     int
  6915.     DECLARE @command        nvarchar(4000)
  6916.  
  6917.     DECLARE @subscriber_security_mode       int                 /* 0 standard; 1 integrated */
  6918.     DECLARE @subscriber_login               sysname 
  6919.     DECLARE @subscriber_password            nvarchar(524) 
  6920.     DECLARE @subscriber_datasource_type     int     /* 0 SQL Server, 1 ODBC, 2 Jet, 3 OLEDB */
  6921.     DECLARE @distributor                    sysname 
  6922.     DECLARE @distributor_security_mode      int                     /* 0 standard; 1 integrated */
  6923.     DECLARE @distributor_login              sysname 
  6924.     DECLARE @distributor_password           nvarchar(524)
  6925.     DECLARE @database                       sysname
  6926.     DECLARE @agent_id                       int
  6927.     DECLARE @category_name                  sysname
  6928.     DECLARE @dsn_subscriber                 tinyint
  6929.     DECLARE @jet_subscriber                 tinyint
  6930.     DECLARE @oledb_subscriber               tinyint
  6931.     DECLARE @exchange_subscriber            tinyint
  6932.     DECLARE @oracle_subscriber              tinyint
  6933.     DECLARE @db2universal_subscriber        tinyint
  6934.     DECLARE @platform_nt                    binary
  6935.     DECLARE @provider_name                    sysname
  6936.  
  6937.     set @subscriber_security_mode = 1
  6938.     set @subscriber_login = NULL
  6939.     set @subscriber_password = NULL
  6940.     set @distributor = @@SERVERNAME
  6941.  
  6942.     set @dsn_subscriber = 1    /* Const: subscriber type 'dsn' */ 
  6943.     set @jet_subscriber = 2   
  6944.     set @oledb_subscriber = 3 
  6945.     set @exchange_subscriber = 4
  6946.     set @oracle_subscriber = 5 
  6947.     set @db2universal_subscriber = 6
  6948.  
  6949.     set @platform_nt = 0x1  
  6950.     
  6951.     -- Set null @optional_command_line to empty string to avoid string concat problem
  6952.     if @optional_command_line is null
  6953.         set @optional_command_line = ''
  6954.     else
  6955.         set @optional_command_line = N' ' + LTRIM( RTRIM(@optional_command_line) ) + N' '
  6956.  
  6957.     -- Get subscriber security context
  6958.     select  @subscriber_security_mode = security_mode,
  6959.             @subscriber_login = login,
  6960.             @subscriber_password = password
  6961.         from MSsubscriber_info where
  6962.             UPPER(publisher) = UPPER(@publisher) and
  6963.             UPPER(subscriber) = UPPER(@subscriber)
  6964.             
  6965.     -- Always use integrated security on winNT
  6966.     if (@platform_nt = platform() & @platform_nt )
  6967.         set @distributor_security_mode = 1
  6968.     else
  6969.     begin
  6970.         select  @distributor_security_mode = 0,
  6971.                 @distributor_login  = login,
  6972.                 @distributor_password = password
  6973.             from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername)
  6974.     end
  6975.     
  6976.     /*
  6977.     ** Initializations
  6978.     */
  6979.     -- Get subscriber info
  6980.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  6981.     select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  6982.  
  6983.     select @subscriber_datasource_type = type
  6984.         from MSsubscriber_info 
  6985.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  6986.  
  6987.     /*
  6988.     ** Jet and Oracle subscribers are actually added to MSsubscriber_info as OLE DB subscribers,
  6989.     ** since they can be used in transactional replication also.
  6990.     ** Map the type to Jet or Oracle based on OLE DB provider name.
  6991.     */
  6992.     if (@subscriber_datasource_type = @oledb_subscriber) 
  6993.     BEGIN
  6994.         select @provider_name = providername from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  6995.         if (upper(@provider_name) = 'MICROSOFT.JET.OLEDB.4.0')
  6996.             select @subscriber_datasource_type = @jet_subscriber
  6997.         else if (upper(@provider_name) = 'MSDAORA')
  6998.             select @subscriber_datasource_type = @oracle_subscriber
  6999.         else if (upper(@provider_name) = 'DB2OLEDB')
  7000.             select @subscriber_datasource_type = @db2universal_subscriber
  7001.     END
  7002.     
  7003.     if (@subscriber_datasource_type IS NULL)
  7004.         select @subscriber_datasource_type = 0
  7005.  
  7006.     -- if @name is not null, the proc is from DMO scripting
  7007.     -- check to see if the job is there are not, if not, reset @job_existing and
  7008.     -- @name values. This is for the case when the user generate the script at
  7009.     -- the publisher but did not re-create repl jobs at the distributor.
  7010.     if @local_job = 1 and @name is not null and 
  7011.        @name <> N''
  7012.     begin
  7013.         if not exists (select * from msdb..sysjobs_view where 
  7014.             name = @name and
  7015.             UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName'))))
  7016.         begin
  7017.             set @name = null
  7018.         end
  7019.     end
  7020.  
  7021.     BEGIN TRAN
  7022.  
  7023.     -- Try to drop it first
  7024.     EXEC dbo.sp_MSdrop_merge_agent 
  7025.         @publisher = @publisher,
  7026.         @publisher_db = @publisher_db,
  7027.         @publication = @publication,
  7028.         @subscriber = @subscriber,
  7029.         @subscriber_db = @subscriber_db
  7030.           
  7031.     IF @@ERROR <> 0
  7032.         GOTO UNDO
  7033.  
  7034.     /* Code for merge agent type in MSagent_profiles */
  7035.     SELECT @merge_type = 4
  7036.  
  7037.     SELECT @profile_id = profile_id
  7038.     FROM msdb..MSagent_profiles
  7039.     WHERE agent_type = @merge_type
  7040.         AND def_profile = 1
  7041.  
  7042.     IF @profile_id IS NULL
  7043.         RETURN (1)
  7044.  
  7045.     /* 
  7046.     ** Insert row
  7047.     */
  7048.     INSERT INTO MSmerge_agents (name, publisher_id, publisher_db, publication, 
  7049.          subscriber_id, subscriber_db, local_job, profile_id)
  7050.          VALUES ('',@publisher_id, @publisher_db, @publication, 
  7051.          @subscriber_id, @subscriber_db, @local_job, @profile_id)
  7052.     IF @@ERROR <> 0
  7053.         GOTO UNDO
  7054.  
  7055.     set @agent_id = @@IDENTITY
  7056.     
  7057.     if @frequency_type is NULL
  7058.         set @frequency_type = 4     /* Daily */
  7059.     if @frequency_interval is NULL
  7060.         set @frequency_interval = 1
  7061.     if @frequency_relative_interval is NULL
  7062.         set @frequency_relative_interval = 1
  7063.     if @frequency_recurrence_factor is NULL
  7064.         set @frequency_recurrence_factor = 0
  7065.     if @frequency_subday is NULL
  7066.         set @frequency_subday = 8   /* Hour */
  7067.     if @frequency_subday_interval is NULL
  7068.         set @frequency_subday_interval = 1
  7069.     if @active_start_time_of_day is NULL
  7070.         set @active_start_time_of_day = 0
  7071.     if @active_end_time_of_day is NULL
  7072.         set @active_end_time_of_day = 235959
  7073.     if @active_start_date is NULL
  7074.         set @active_start_date = 0
  7075.     if @active_end_date is NULL
  7076.         set @active_end_date = 99991231
  7077.  
  7078.     declare @job_existing bit
  7079.     IF @name IS NULL OR @name = N''
  7080.     begin
  7081.         SELECT @name = CONVERT(nvarchar(21),@publisher ) + '-' + CONVERT(nvarchar(21),@publisher_db) + '-' + 
  7082.                         CONVERT(nvarchar(21),@publication) + '-' + CONVERT(nvarchar(21),@subscriber) + '-' +
  7083.                             CONVERT(nvarchar, @@IDENTITY)
  7084.         select @job_existing = 0
  7085.     end
  7086.     else
  7087.         select @job_existing = 1
  7088.     
  7089.     -- If creating a new job and the generated name already exists, re-generate the name with a 
  7090.     -- guid appended
  7091.     IF  @job_existing = 0
  7092.     BEGIN
  7093.         IF EXISTS (SELECT * FROM msdb..sysjobs_view 
  7094.                     WHERE name = @name 
  7095.                       AND UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName'))))
  7096.         BEGIN
  7097.             SELECT @name = fn_repluniquename(newid(), @publisher, @publisher_db, 
  7098.                 @publication, @subscriber)
  7099.         END            
  7100.     END
  7101.  
  7102.     -- Add Perfmoon instance
  7103.     dbcc addinstance ("SQL Replication Merge", @name)
  7104.  
  7105.     IF @local_job = 1
  7106.     BEGIN
  7107.         if @job_existing = 0
  7108.         begin
  7109.  
  7110.             /* Construct task command */
  7111.  
  7112.             select @command = '-Publisher ' + QUOTENAME(@publisher) + ' -PublisherDB ' + QUOTENAME(@publisher_db) + ' '
  7113.             select @command = @command + '-Publication ' + QUOTENAME(@publication) + ' '
  7114.             select @command = @command + '-Subscriber ' + QUOTENAME(@subscriber)  + ' '
  7115.  
  7116.             if (@subscriber_datasource_type = 0)
  7117.                 select @command = @command + '-SubscriberDB ' + QUOTENAME(@subscriber_db) + ' '
  7118.         
  7119.             if (@subscriber_datasource_type <> 0)
  7120.                 select @command = @command + '-SubscriberType ' + convert(nvarchar(10),@subscriber_datasource_type) + ' '
  7121.     
  7122.             select @command = @command + @optional_command_line
  7123.             select @command = @command + '-Distributor ' + QUOTENAME(@distributor) + ' '
  7124.  
  7125.             select @command = @command + '-DistributorSecurityMode ' + 
  7126.                 convert(nvarchar(10),@distributor_security_mode) +  ' ' 
  7127.             if @distributor_security_mode <> 1
  7128.             begin
  7129.                 if @distributor_login is not NULL
  7130.                     select @command = @command + '-DistributorLogin ' + @distributor_login + ' '
  7131.                 if @distributor_password is not NULL
  7132.                     select @command = @command + '-DistributorEncryptedPassword ' + quotename(@distributor_password) + ' '
  7133.             end
  7134.  
  7135.             select @database = db_name()
  7136.  
  7137.             -- Get Merge category name (assumes category_id = 14)
  7138.             select @category_name = name FROM msdb.dbo.syscategories where category_id = 14
  7139.  
  7140.             EXEC @retcode = dbo.sp_MSadd_repl_job
  7141.                     @name = @name,
  7142.                     @subsystem = 'Merge',
  7143.                     @server = @@SERVERNAME,
  7144.                     @databasename = @database,
  7145.                     @enabled = 1,
  7146.                     @freqtype = @frequency_type,
  7147.                     @freqinterval = @frequency_interval,
  7148.                     @freqsubtype = @frequency_subday,
  7149.                     @freqsubinterval = @frequency_subday_interval,
  7150.                     @freqrelativeinterval = @frequency_relative_interval,
  7151.                     @freqrecurrencefactor = @frequency_recurrence_factor,
  7152.                     @activestartdate = @active_start_date,
  7153.                     @activeenddate = @active_end_date,
  7154.                     @activestarttimeofday = @active_start_time_of_day,
  7155.                     @activeendtimeofday = @active_end_time_of_day,
  7156.                     @command = @command,
  7157.                     @category_name = @category_name,
  7158.                     @failure_detection = 1,
  7159.                     @agent_id = @agent_id,
  7160.                     @retryattempts = 10,
  7161.                     @retrydelay = 1,
  7162.                     @job_id = @merge_jobid OUTPUT
  7163.             
  7164.             if @@ERROR <> 0 or @retcode <> 0
  7165.                 goto UNDO
  7166.         end
  7167.         else
  7168.         begin
  7169.             select @merge_jobid = job_id from msdb..sysjobs_view where 
  7170.                 name = @name and
  7171.                 UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName')))
  7172.             if @merge_jobid IS NULL
  7173.             begin
  7174.                 -- Message from msdb.dbo.sp_verify_job_identifiers
  7175.                 RAISERROR(14262, -1, -1, 'Job', @name)          
  7176.                 GOTO UNDO
  7177.             end
  7178.         end
  7179.     END /* for local_job = 1 */
  7180.     ELSE 
  7181.     BEGIN
  7182.         -- Generate a job GUID for remote agents. This will be used by the UI to uniquely
  7183.         -- identify rows returned by the enums
  7184.         set @merge_jobid = newid();
  7185.     END
  7186.             
  7187.     UPDATE MSmerge_agents SET name = @name,
  7188.         job_id = @merge_jobid WHERE
  7189.         id = @agent_id
  7190.  
  7191.     IF @@ERROR <> 0
  7192.         GOTO UNDO
  7193.  
  7194.  
  7195.     IF @subscription_type = 0
  7196.     BEGIN
  7197.         -- Add offload parameter to agent command line if necessary
  7198.         IF @offloadagent = 1 
  7199.         BEGIN
  7200.             EXEC @retcode = sp_MSenableagentoffload @job_id = @merge_jobid,
  7201.                                             @offloadserver = @offloadserver
  7202.         END
  7203.         ELSE
  7204.         BEGIN
  7205.             EXEC @retcode = sp_MSdisableagentoffload @job_id = @merge_jobid,
  7206.                                             @offloadserver = @offloadserver 
  7207.         END
  7208.         IF @@ERROR <> 0 OR @retcode <> 0
  7209.             GOTO UNDO
  7210.  
  7211.     END
  7212.  
  7213.     -- Update global replication status table
  7214.     EXEC dbo.sp_MSupdate_replication_status
  7215.         @publisher,
  7216.         @publisher_db,
  7217.         @publication,
  7218.         @publication_type = 1, -- Merge 
  7219.         @agent_type = 4,
  7220.         @agent_name = @name,
  7221.         @status = 0     -- not running status
  7222.  
  7223.     COMMIT TRAN
  7224.  
  7225.     RETURN(0)
  7226.  
  7227. UNDO:
  7228.     if @@TRANCOUNT = 1
  7229.         ROLLBACK TRAN
  7230.     else
  7231.         COMMIT TRAN
  7232.     return(1)
  7233. GO
  7234.  
  7235. raiserror(15339,-1,-1,'sp_MSdrop_subscription')
  7236. GO
  7237. CREATE PROCEDURE sp_MSdrop_subscription
  7238. @publisher sysname,
  7239. @publisher_db sysname,
  7240. @subscriber sysname,
  7241. @article_id int = NULL,
  7242. @subscriber_db sysname = NULL,
  7243. @publication sysname = NULL,
  7244. @article sysname = NULL
  7245.  
  7246. as
  7247.  
  7248.     set nocount on
  7249.  
  7250.     declare @publisher_id smallint
  7251.     declare @subscriber_id smallint
  7252.     declare @name nvarchar (100)
  7253.     declare @retcode int
  7254.     declare @push tinyint
  7255.     declare @anonymous tinyint
  7256.     declare @keep_for_last_run bit
  7257.     declare @virtual smallint
  7258.     declare @virtual_anonymous smallint
  7259.     declare @independent_agent bit
  7260.     declare @publication_id int
  7261.     declare @subscription_type int
  7262.     declare @thirdparty_flag bit
  7263.     declare @id             int
  7264.     declare @publication_name sysname
  7265.     declare @queued_sub_precount int
  7266.  
  7267.     select @push = 0        -- const: push subscription type 
  7268.     select @anonymous = 2   -- const: push subscription type 
  7269.     select @virtual = -1    -- const: virtual subscriber id 
  7270.     select @virtual_anonymous = -2  -- const: virtual anonymous subscriber id 
  7271.  
  7272.     -- Select the current count of the queued subscribers prior to 
  7273.     -- dropping this subscription
  7274.     select @queued_sub_precount = count(*) from dbo.MSsubscriptions where update_mode in (2,3,4,5)
  7275.  
  7276.     -- Save off name for dummy status row
  7277.     select @publication_name = @publication
  7278.  
  7279.     -- Check if publisher is a defined as a distribution publisher in the current database
  7280.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  7281.     if @retcode <> 0
  7282.     begin
  7283.         return(1)
  7284.     end
  7285.  
  7286.     -- Check if subscriber exists
  7287.     if @subscriber is null
  7288.     begin
  7289.         select @subscriber_id = @virtual
  7290.         -- hardcoded in sp_MSadd_subscription
  7291.         select @subscriber_db = 'virtual'
  7292.     end
  7293.     else
  7294.         select @subscriber_id = srvid from master..sysservers, MSsubscriber_info where 
  7295.             UPPER(srvname) = UPPER(@subscriber) and
  7296.             UPPER(subscriber) = UPPER(@subscriber) and
  7297.             UPPER(publisher) = UPPER(@publisher)
  7298.     if @subscriber_id is NULL
  7299.     begin
  7300.         raiserror (20032, 16, -1, @subscriber, @publisher) 
  7301.         return (1)
  7302.     end
  7303.  
  7304.     -- If publication exists this is a post 6.x publisher
  7305.     if @publication is not NULL
  7306.     begin
  7307.         select @publication_id = publication_id,
  7308.                @thirdparty_flag = thirdparty_flag
  7309.             from MSpublications where
  7310.             publisher_id = @publisher_id and
  7311.             publisher_db = @publisher_db and
  7312.             publication = @publication
  7313.             
  7314.         -- Get article_id 
  7315.         if @article is not NULL and @article_id = 0
  7316.         begin
  7317.             select @article_id = article_id from MSarticles where 
  7318.                 publisher_id = @publisher_id and
  7319.                 publisher_db = @publisher_db and
  7320.                 publication_id = @publication_id and
  7321.                 article = @article
  7322.         end
  7323.         -- Check that subscription exists
  7324.         -- Only do the check for post 6x publisher
  7325.         if not exists (select * from MSsubscriptions where 
  7326.             publisher_id = @publisher_id and 
  7327.             publisher_db = @publisher_db and 
  7328.             publication_id = @publication_id and
  7329.             subscriber_id = @subscriber_id and
  7330.             subscriber_db = @subscriber_db)
  7331.         begin
  7332.             if @thirdparty_flag = 1
  7333.             begin
  7334.                 raiserror (14050, 16, -1)
  7335.                 return(1)
  7336.             end
  7337.             else
  7338.                 return (0)
  7339.         end
  7340.     end
  7341.  
  7342.     -- get the subscription type
  7343.     -- used when dropping dist agent
  7344.     select @subscription_type = subscription_type, 
  7345.         @independent_agent = independent_agent
  7346.         from MSsubscriptions where
  7347.         publisher_id = @publisher_id and
  7348.         publisher_db = @publisher_db and
  7349.         (publication_id = @publication_id or
  7350.          @publication_id is NULL) and
  7351.         (@article_id is NULL or
  7352.         article_id = @article_id) and
  7353.         (subscriber_id = @subscriber_id and
  7354.         (subscriber_db = @subscriber_db or @subscriber_id = @virtual))
  7355.  
  7356.     begin transaction
  7357.     save transaction MSdrop_subscription
  7358.  
  7359.     -- Delete the subscription 
  7360.     -- For anonymous type, delete virtual anonymous subscription also
  7361.     -- if deleting the  virtual subscription 
  7362.     -- (since there can be only one subscriber_id per article, subscriber_db doesn't matter)
  7363.     delete from MSsubscriptions where
  7364.         publisher_id = @publisher_id and
  7365.         publisher_db = @publisher_db and
  7366.         (publication_id = @publication_id or
  7367.          @publication_id is NULL) and
  7368.         (@article_id is NULL or
  7369.         article_id = @article_id) and
  7370.         ((subscriber_id = @subscriber_id and
  7371.         (subscriber_db = @subscriber_db or @subscriber_id = @virtual)) or
  7372.         -- Delete virtual anonymous subscription 
  7373.         -- if deleting virtual subscription for a anonymous publication
  7374.        (@subscriber_id = @virtual and subscriber_id = @virtual_anonymous))
  7375.  
  7376.     if @@error <> 0
  7377.     begin
  7378.         if @@trancount > 0
  7379.         begin
  7380.             rollback transaction MSdrop_subscription
  7381.             commit transaction  -- to finish off the tran we started in this proc (though 
  7382.                             -- work was rolled back to savepoint)
  7383.         end
  7384.         return 1
  7385.     end
  7386.     
  7387.     -- If it is the last subscription for the distribution agent, drop the dist agent
  7388.     if not exists (select * from MSsubscriptions    where
  7389.         publisher_id = @publisher_id and
  7390.         publisher_db = @publisher_db and
  7391.         (publication_id = @publication_id or
  7392.         @publication_id is NULL or
  7393.          @independent_agent = 0 ) and
  7394.         independent_agent = @independent_agent and
  7395.         subscriber_id = @subscriber_id and
  7396.         subscriber_db = @subscriber_db and
  7397.         subscription_type = @subscription_type)
  7398.     begin
  7399.         -- Harded coded in sp_MSadd_subscription.
  7400.         if @independent_agent = 0
  7401.             select @publication = 'ALL'
  7402.         /*
  7403.         ** Get agentid to check history record
  7404.         */
  7405.         select @id=id from MSdistribution_agents where 
  7406.         publisher_id = @publisher_id and
  7407.         publisher_db = @publisher_db and
  7408.         publication = @publication and
  7409.         subscriber_id = @subscriber_id and
  7410.         subscriber_db = @subscriber_db
  7411.  
  7412.     /*
  7413.     ** If the subscription has not yet been synced, there is no need for subscriber side cleanup 
  7414.     ** therefore no need for the last agent run.
  7415.     */
  7416.     if exists (select * from MSdistribution_history where agent_id = @id)
  7417.         select @keep_for_last_run = 0 -- default is not to do cleanup
  7418.     else 
  7419.         select @keep_for_last_run = 0
  7420.  
  7421.  
  7422.     /*
  7423.     ** Delete distribution task.
  7424.     */
  7425.         execute @retcode = dbo.sp_MSdrop_distribution_agent 
  7426.             @publisher_id = @publisher_id,
  7427.             @publisher_db = @publisher_db,
  7428.             @publication = @publication,
  7429.             @subscriber_id = @subscriber_id,
  7430.             @subscriber_db = @subscriber_db,
  7431.             @subscription_type = @subscription_type,
  7432.             @keep_for_last_run = @keep_for_last_run  
  7433.  
  7434.         if @@error <> 0 or @retcode <> 0
  7435.         begin
  7436.             if @@trancount > 0
  7437.             begin
  7438.                 rollback transaction MSdrop_subscription
  7439.                 commit transaction  -- to finish off the tran we started in this proc (though 
  7440.                                 -- work was rolled back to savepoint)
  7441.             end
  7442.             return 1
  7443.         end
  7444.     end
  7445.  
  7446.     
  7447.     -- Delete anonymous agents that are not in subscription table anymore
  7448.     -- It is due to dropping articles. Don't raise messages
  7449.     if @subscriber_id = @virtual
  7450.     begin
  7451.         delete MSdistribution_agents where
  7452.             anonymous_agent_id is not null and 
  7453.             not exists (select * from MSsubscriptions s where
  7454.                 s.agent_id = anonymous_agent_id)
  7455.  
  7456.  
  7457.         if @@error <> 0
  7458.         begin
  7459.             if @@trancount > 0
  7460.             begin
  7461.                 rollback transaction MSdrop_subscription
  7462.                 commit transaction  -- to finish off the tran we started in this proc (though 
  7463.                                 -- work was rolled back to savepoint)
  7464.             end
  7465.             return 1
  7466.         end
  7467.     end
  7468.  
  7469.  
  7470.     -- delete any rows in syncstate tracking table
  7471.  
  7472.     delete MSsync_states where 
  7473.         publisher_id = @publisher_id and
  7474.         publisher_db = @publisher_db and
  7475.         publication_id = @publication_id 
  7476.  
  7477.     if @@error <> 0
  7478.     begin
  7479.         if @@trancount > 0
  7480.         begin
  7481.             rollback transaction MSdrop_subscription
  7482.             commit transaction  -- to finish off the tran we started in this proc (though 
  7483.                             -- work was rolled back to savepoint)
  7484.         end
  7485.         return 1
  7486.     end
  7487.  
  7488.  
  7489.     commit transaction
  7490.  
  7491.     --  Add dummy distribution aent row entry for publication.  This will allow the status
  7492.     --  for the shared distribution agent to be restricted
  7493.     if @publication_name IS NOT NULL
  7494.     begin
  7495.         EXEC dbo.sp_MSupdate_replication_status
  7496.             @publisher,
  7497.             @publisher_db,
  7498.             @publication_name, 
  7499.             @agent_type = 3,   
  7500.             @agent_name = NULL, 
  7501.             @status = -1    -- delete
  7502.     end
  7503.  
  7504.     -- Refresh global status table. 
  7505.     EXEC dbo.sp_MSupdate_replication_status
  7506.         @publisher,
  7507.         @publisher_db,
  7508.         @publication = '%',    -- refresh the publisher node.
  7509.         @agent_type = NULL,    -- Not used    with @status = -2
  7510.         @agent_name = NULL, -- Not used with @status = -2
  7511.         @status = -2    -- refresh status
  7512.  
  7513.     -- Check to see if we need to drop the qreader agent
  7514.     if (@@error = 0 and @queued_sub_precount = 1 and
  7515.         not exists (select * from dbo.MSsubscriptions where update_mode in (2,3,4,5)))
  7516.     begin
  7517.         declare @agent_id int
  7518.         
  7519.         select top 1 @agent_id = id from dbo.MSqreader_agents
  7520.         if (@agent_id is not null)
  7521.             execute dbo.sp_MSdrop_qreader_agent @agent_id
  7522.     end    
  7523.  
  7524. GO
  7525.  
  7526. raiserror(15339,-1,-1,'sp_MSadd_subscription')
  7527. GO
  7528. CREATE PROCEDURE sp_MSadd_subscription
  7529. @publisher sysname,
  7530. @publisher_db sysname,
  7531. @subscriber sysname,       
  7532. @article_id int = NULL,
  7533. @subscriber_db sysname = NULL,
  7534. @status tinyint,                    -- 0 = inactive, 1 = subscribed, 2 = active 
  7535. @subscription_seqno varbinary(16),  -- publisher's database sequence number 
  7536.  
  7537. -- Post 6.5 parameters
  7538. @publication sysname = NULL,    -- 6.x publishers will not provide this
  7539. @article sysname = NULL,
  7540. @subscription_type tinyint = 0,     -- 0 = push, 1 = pull, 2 = anonymous 
  7541. @sync_type tinyint = 0,             -- 0 = none  1 = automatic snaphot  2 = no intial snapshot
  7542. @snapshot_seqno_flag bit = 0,       -- 1 = subscription seqno is the snapshot seqno
  7543.  
  7544. @frequency_type int = NULL,
  7545. @frequency_interval int = NULL,
  7546. @frequency_relative_interval int = NULL,
  7547. @frequency_recurrence_factor int = NULL,
  7548. @frequency_subday int = NULL,
  7549. @frequency_subday_interval int = NULL,
  7550. @active_start_time_of_day int = NULL,
  7551. @active_end_time_of_day int = NULL,
  7552. @active_start_date int = NULL,
  7553. @active_end_date int = NULL,
  7554. @optional_command_line nvarchar(4000) = '',
  7555.  
  7556. -- synctran
  7557. @update_mode tinyint = 0, -- 0 = read only, 1 = sync tran, 2 = queued tran, 
  7558.                           -- 3 = failover, 4 = sqlqueued tran, 5 = sqlqueued failover
  7559. @loopback_detection bit = 0,
  7560. @distribution_jobid binary(16) = NULL OUTPUT,
  7561.  
  7562. -- agent offload
  7563. @offloadagent  bit = 0,
  7564. @offloadserver sysname = NULL,
  7565.  
  7566. -- If agent is already created, the package name will be ignored.         
  7567. @dts_package_name sysname = NULL,
  7568. @dts_package_password nvarchar(524) = NULL,
  7569. @dts_package_location    int = 0,
  7570. @distribution_job_name sysname = NULL
  7571.  
  7572. as
  7573.  
  7574.     set nocount on
  7575.     declare @publisher_id smallint
  7576.     declare @subscriber_id smallint
  7577.     declare @command nvarchar (4000)
  7578.     declare @type tinyint
  7579.     declare @database sysname
  7580.     declare @long_name nvarchar (255)
  7581.     declare @retcode int
  7582.     declare @login sysname
  7583.     declare @password nvarchar(524)
  7584.     declare @retryattempts int
  7585.     declare @retrydelay int
  7586.     declare @virtual smallint                       -- const: virtual subscriber id 
  7587.     declare @virtual_anonymous smallint                 -- const: virtual anonymous subscriber id 
  7588.     declare @publication_str nvarchar (32)
  7589.     declare @agent_id int
  7590.     declare @publication_id int
  7591.     declare @independent_agent bit
  7592.     declare @allow_pull bit
  7593.     declare @active tinyint
  7594.  
  7595.     declare @flushfrequency int 
  7596.     declare @frequencytype int
  7597.     declare @frequencyinterval int 
  7598.     declare @frequencyrelativeinterval int
  7599.     declare @frequencyrecurrencefactor int 
  7600.     declare @frequencysubday int 
  7601.     declare @frequencysubdayinterval int
  7602.     declare @activestarttimeofday int
  7603.     declare @activeendtimeofday int
  7604.     declare @activestartdate int 
  7605.     declare @activeenddate int 
  7606.     DECLARE @dsn_subscriber tinyint
  7607.     DECLARE @jet_subscriber tinyint
  7608.     DECLARE @oledb_subscriber tinyint
  7609.     declare @thirdparty_flag bit
  7610.  
  7611.     DECLARE @distributor_security_mode      int                     /* 0 standard; 1 integrated */
  7612.     DECLARE @distributor_login              sysname 
  7613.     DECLARE @distributor_password           nvarchar(524)
  7614.     DECLARE @publisher_database_id int
  7615.     DECLARE @platform_nt binary
  7616.     declare @anonymous_agent_id int
  7617.     DECLARE @agent_name nvarchar(100)
  7618.     DECLARE @publication_name sysname
  7619.  
  7620.     -- Store off publication name for dummy monitor row
  7621.     select @publication_name = @publication
  7622.  
  7623.     -- Defined in sqlrepl.h
  7624.     -- Set null @optional_command_line to empty string to avoid string concat problem
  7625.     if @optional_command_line is null
  7626.         set @optional_command_line = ''
  7627.     else
  7628.         set @optional_command_line = N' ' + LTRIM( RTRIM(@optional_command_line) ) + N' '
  7629.  
  7630.     select @dsn_subscriber = 1    /* Const: subscriber type 'dsn' */ 
  7631.     select @jet_subscriber = 2   
  7632.     select @oledb_subscriber = 3   
  7633.  
  7634.     select @virtual = -1
  7635.     select @virtual_anonymous = -2
  7636.  
  7637.     select @active = 2
  7638.  
  7639.     select @platform_nt = 0x1
  7640.  
  7641.     -- Check if publisher is a defined as a distribution publisher in the current database
  7642.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  7643.     if @retcode <> 0 or @@error <> 0
  7644.     begin
  7645.         return(1)
  7646.     end
  7647.  
  7648.     -- Check if subscriber exists
  7649.     if @subscriber is null
  7650.     begin
  7651.       select @subscriber_id = @virtual
  7652.       -- The following 2 variables are hardcoded in sp_MSget_repl_cmds_anonymous 
  7653.       select @subscriber_db = 'virtual'
  7654.       select @subscription_type = 0
  7655.     end
  7656.     else
  7657.         select @subscriber_id = srvid from master..sysservers, MSsubscriber_info where 
  7658.             UPPER(srvname) = UPPER(@subscriber) and
  7659.             UPPER(subscriber) = UPPER(@subscriber) and
  7660.             UPPER(publisher) = UPPER(@publisher)
  7661.     if @subscriber_id is NULL
  7662.     begin
  7663.         raiserror (20032, 16, -1, @subscriber, @publisher) 
  7664.         return (1)
  7665.     end
  7666.     -- Special logic for 6.5 publisher.
  7667.     -- If publisher_id, publisher_db pair is not in MSpublisher_databases then add it.  This will be used
  7668.     -- to store a publisher_database_id in the MSrepl_transactions and MSrepl_commands table.
  7669.     if @publication is null
  7670.     begin
  7671.         if not exists (select * from MSpublisher_databases where publisher_id = @publisher_id and
  7672.             publisher_db = @publisher_db)
  7673.         begin
  7674.             insert into MSpublisher_databases (publisher_id, publisher_db) values (@publisher_id, @publisher_db)
  7675.             if @@error <> 0
  7676.                 goto UNDO
  7677.         end
  7678.     end
  7679.     
  7680.     -- Get publisher_database_id
  7681.     select @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and
  7682.         publisher_db = @publisher_db
  7683.     if @@error <> 0
  7684.         return 1
  7685.  
  7686.     -- If publication exists this is a post 6.x publisher
  7687.     if @publication is not NULL
  7688.     begin
  7689.         select @publication_id = publication_id, 
  7690.             @independent_agent = independent_agent, @allow_pull = allow_pull,
  7691.             @thirdparty_flag = thirdparty_flag from 
  7692.             MSpublications where 
  7693.             publisher_id = @publisher_id and
  7694.             publisher_db = @publisher_db and
  7695.             publication = @publication
  7696.         if @publication_id is NULL
  7697.         begin
  7698.             raiserror (20026, 11, -1, @publication)
  7699.             return (1)
  7700.         end
  7701.  
  7702.         -- Check if article_id exists
  7703.         if @article_id is not NULL 
  7704.         begin
  7705.             if not exists (select * from MSarticles where 
  7706.                 publisher_id = @publisher_id and
  7707.                 publisher_db = @publisher_db and
  7708.                 article_id = @article_id)
  7709.             begin
  7710.                 raiserror (20027, 11, -1, @article) 
  7711.                 return (1)
  7712.             end
  7713.         end
  7714.  
  7715.         -- Check if article exists
  7716.         if @article is not NULL and @article_id is NULL
  7717.         begin
  7718.             select @article_id = article_id from MSarticles where 
  7719.                 publisher_id = @publisher_id and
  7720.                 publisher_db = @publisher_db and
  7721.                 article = @article
  7722.             if @article_id is NULL
  7723.             begin
  7724.                 raiserror (20027, 11, -1, @article) 
  7725.                 return (1)
  7726.             end
  7727.         end
  7728.     end
  7729.     else
  7730.     begin   -- Set 6.x publishing values
  7731.         select @publication_id = 0
  7732.         select @independent_agent = 0
  7733.         select @allow_pull = 0
  7734.         select @thirdparty_flag = 0
  7735.     end
  7736.  
  7737.     -- Make sure subscription does not already exist
  7738.     if exists (select * from MSsubscriptions where 
  7739.         publisher_id = @publisher_id and 
  7740.         publisher_db = @publisher_db and 
  7741.         publication_id = @publication_id and
  7742.         article_id = @article_id and
  7743.         subscriber_id = @subscriber_id and
  7744.         subscriber_db = @subscriber_db)
  7745.     begin
  7746.         if @thirdparty_flag = 1
  7747.         begin
  7748.             raiserror (14058, 16, -1)
  7749.             return(1)
  7750.         end
  7751.         else
  7752.         begin
  7753.             exec @retcode = dbo.sp_MSdrop_subscription
  7754.                 @publisher = @publisher,
  7755.                 @publisher_db = @publisher_db,
  7756.                 @subscriber = @subscriber,
  7757.                 @article_id = @article_id,
  7758.                 @subscriber_db = @subscriber_db,
  7759.                 @publication = @publication,
  7760.                 @article = @article
  7761.             if @retcode <> 0 or @@error <> 0
  7762.             begin
  7763.                 return(1)
  7764.             end
  7765.         end
  7766.     end
  7767.  
  7768.     -- Check to see if we need to add a new distribution agent for the subscription.
  7769.     -- It is database wide for non independent agent publications, and publication wide otherwise.
  7770.     -- Check to see if the distribution agent for this subscription is already added.
  7771.  
  7772.     select @agent_id = NULL
  7773.     select @agent_id = agent_id from 
  7774.         MSsubscriptions where
  7775.         publisher_id = @publisher_id and
  7776.         publisher_db = @publisher_db and
  7777.         subscription_type = @subscription_type and
  7778.         (publication_id = @publication_id or @independent_agent = 0) and
  7779.         independent_agent = @independent_agent and 
  7780.         subscriber_id = @subscriber_id and
  7781.         subscriber_db = @subscriber_db
  7782.  
  7783.     if @subscriber_id = @virtual
  7784.     begin
  7785.         select @anonymous_agent_id = agent_id from 
  7786.             MSsubscriptions where
  7787.             publisher_id = @publisher_id and
  7788.             publisher_db = @publisher_db and
  7789.             subscription_type = @subscription_type and
  7790.             (publication_id = @publication_id or @independent_agent = 0) and
  7791.             independent_agent = @independent_agent and 
  7792.             subscriber_id = @virtual_anonymous and
  7793.             subscriber_db = @subscriber_db
  7794.     end
  7795.     
  7796.     -- Always use integrated security on winNT
  7797.     if (@platform_nt = platform() & @platform_nt )
  7798.         set @distributor_security_mode = 1
  7799.     else
  7800.     begin
  7801.         select  @distributor_security_mode = 0,
  7802.                 @distributor_login  = login,
  7803.                 @distributor_password = password
  7804.             from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername)
  7805.     end
  7806.  
  7807.     --Get default task parameter values from MSsubscriber_info 
  7808.     select @type = type
  7809.     from MSsubscriber_info 
  7810.     where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  7811.  
  7812.     -- Only SQL Server and OLEDB subscriber support dts
  7813.     if @dts_package_name is not null and @type not in (0, @oledb_subscriber)
  7814.     begin
  7815.         -- Only sqlserver or oledb sub are allowed
  7816.         raiserror(21170, 16, -1)
  7817.         return 1
  7818.     end
  7819.  
  7820.     begin tran
  7821.     save transaction MSadd_subscription
  7822.  
  7823.     if @agent_id is NOT NULL
  7824.     begin
  7825.         select @distribution_jobid = job_id from MSdistribution_agents
  7826.             where id = @agent_id
  7827.     end
  7828.     else
  7829.     begin
  7830.  
  7831.  
  7832.         -- Create distribution agent
  7833.         -- Do not create local job if
  7834.         -- 1. virtual subscription 
  7835.         -- 2. no subscriber information, return (6.x legacy)
  7836.         -- 3. pull (this sp will not be called for anonymous subscription)
  7837.  
  7838.         declare @local_job bit
  7839.  
  7840.         if @subscriber_id = @virtual or 
  7841.             not exists (select * from MSsubscriber_info where
  7842.                 UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)) OR 
  7843.             @subscription_type = 1 
  7844.  
  7845.             select @local_job = 0
  7846.         else
  7847.             select @local_job = 1
  7848.  
  7849.         -- 'ALL' is reserved for indication all publications
  7850.         -- Hardcoded in sp_MSenum*... 
  7851.         -- Note! @publication is overwritten
  7852.         
  7853.         if @independent_agent = 0
  7854.             select @publication = 'ALL'
  7855.  
  7856.         if @local_job = 1
  7857.         begin
  7858.             select 
  7859.                 @frequencytype = frequency_type,
  7860.                 @frequencyinterval = frequency_interval,
  7861.                 @frequencyrelativeinterval = frequency_relative_interval,
  7862.                 @frequencyrecurrencefactor = frequency_recurrence_factor,
  7863.                 @frequencysubday = frequency_subday,
  7864.                 @frequencysubdayinterval = frequency_subday_interval,
  7865.                 @activestarttimeofday = active_start_time_of_day,
  7866.                 @activeendtimeofday = active_end_time_of_day,
  7867.                 @activestartdate = active_start_date,
  7868.                 @activeenddate = active_end_date
  7869.             from MSsubscriber_schedule 
  7870.             where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0    
  7871.  
  7872.             if @frequency_type is null
  7873.                 select @frequency_type = @frequencytype
  7874.  
  7875.             if @frequency_interval  is null
  7876.                 select  @frequency_interval = @frequencyinterval
  7877.  
  7878.             if @frequency_relative_interval is null
  7879.                 select  @frequency_relative_interval = @frequencyrelativeinterval
  7880.  
  7881.             if @frequency_recurrence_factor is null
  7882.                 select  @frequency_recurrence_factor = @frequencyrecurrencefactor
  7883.  
  7884.             if @frequency_subday is null
  7885.                 select  @frequency_subday = @frequencysubday
  7886.  
  7887.             if @frequency_subday_interval is null
  7888.                 select  @frequency_subday_interval = @frequencysubdayinterval
  7889.  
  7890.             if @active_start_time_of_day is null
  7891.                 select  @active_start_time_of_day = @activestarttimeofday
  7892.  
  7893.             if @active_end_time_of_day is null
  7894.                 select  @active_end_time_of_day = @activeendtimeofday
  7895.  
  7896.             if @active_start_date is null
  7897.                 select  @active_start_date = @activestartdate
  7898.  
  7899.             if @active_end_date is null
  7900.                 select  @active_end_date = @activeenddate
  7901.  
  7902.             -- Construct task command 
  7903.             select @command = '-Subscriber ' + QUOTENAME(@subscriber)  + ' '
  7904.  
  7905.             declare @dsn_dbname sysname
  7906.             SELECT @dsn_dbname = formatmessage(20586)
  7907.             -- DSN subscribers don't have a subscriber db name.
  7908.             if @subscriber_db is not NULL --AND @type NOT IN( @dsn_subscriber,@jet_subscriber, @oledb_subscriber)
  7909.             -- 7.0 publisher still uses DSN. 8.0 publisher use localized '(default destination)'
  7910.             -- ActiveX may use unlocalized '(default destination)'
  7911.             AND @subscriber_db NOT IN( N'(default destination)', N'DSN', @dsn_dbname)
  7912.             begin
  7913.                 select @command = @command  + '-SubscriberDB ' + QUOTENAME(@subscriber_db) + ' '
  7914.             end
  7915.             select @command = @command + '-Publisher ' + QUOTENAME(@publisher) + ' '
  7916.             select @command = @command + '-Distributor ' + QUOTENAME(@@SERVERNAME) + ' '
  7917.  
  7918.             select @command = @command + '-DistributorSecurityMode ' + 
  7919.                 convert(nvarchar(10),@distributor_security_mode) +  ' ' 
  7920.             if @distributor_security_mode <> 1
  7921.             begin
  7922.                 if @distributor_login is not NULL
  7923.                     select @command = @command + '-DistributorLogin ' + @distributor_login + ' '
  7924.                 if @distributor_password is not NULL
  7925.                     select @command = @command + '-DistributorEncryptedPassword ' + quotename(@distributor_password) + ' '
  7926.             end
  7927.  
  7928.             if @independent_agent = 1
  7929.                 select @command = @command +'-Publication ' + QUOTENAME(@publication) + ' '
  7930.  
  7931.             if @publisher_db is not NULL
  7932.                 select @command = @command + '-PublisherDB ' + QUOTENAME(@publisher_db) + ' '
  7933.  
  7934.             if @type = @dsn_subscriber or @type = @oledb_subscriber
  7935.               select @command = @command + '-SubscriberType ' + convert (nvarchar(10),@type) + ' '
  7936.             
  7937.             if @dts_package_name is not null
  7938.               select @command = @command + '-UseDTS '
  7939.             
  7940.  
  7941.             -- 64 is auto-start. Agents should be in continuous mode. sp_MSadd_repl_job will append "-Continuous" to the end of command line
  7942.  
  7943.             if datalength(@command) + datalength(@optional_command_line) > 8000
  7944.             begin
  7945.                 RAISERROR(20018, 16, -1)
  7946.                 RETURN(1)
  7947.             end
  7948.             select @command = @command + @optional_command_line
  7949.             
  7950.             execute @retcode = dbo.sp_MSadd_distribution_agent
  7951.                 @publisher_id = @publisher_id,
  7952.                 @publisher_db = @publisher_db,
  7953.                 @publication = @publication,
  7954.                 @subscriber_id = @subscriber_id,
  7955.                 @subscriber_db = @subscriber_db,
  7956.                 @subscription_type = @subscription_type,
  7957.                 @local_job = @local_job,
  7958.                 @frequency_type = @frequency_type,
  7959.                 @frequency_interval = @frequency_interval,
  7960.                 @frequency_subday = @frequency_subday,
  7961.                 @frequency_subday_interval = @frequency_subday_interval,
  7962.                 @frequency_relative_interval = @frequency_relative_interval,
  7963.                 @frequency_recurrence_factor = @frequency_recurrence_factor,
  7964.                 @active_start_date = @active_start_date,
  7965.                 @active_end_date = @active_end_date,
  7966.                 @active_start_time_of_day = @active_start_time_of_day,
  7967.                 @active_end_time_of_day = @active_end_time_of_day,
  7968.                 @command = @command,
  7969.                 @agent_id = @agent_id OUTPUT,
  7970.                 @distribution_jobid = @distribution_jobid OUTPUT,
  7971.                 @update_mode = @update_mode,
  7972.                 @offloadagent = @offloadagent,
  7973.                 @offloadserver = @offloadserver,
  7974.                 @dts_package_name = @dts_package_name,
  7975.                 @dts_package_password = @dts_package_password,
  7976.                 @dts_package_location = @dts_package_location,
  7977.                 @name = @distribution_job_name
  7978.  
  7979.  
  7980.             if @@error <> 0 or @retcode <> 0
  7981.                 goto UNDO
  7982.         end
  7983.         else
  7984.         begin
  7985.             execute @retcode = dbo.sp_MSadd_distribution_agent
  7986.                 @publisher_id = @publisher_id,
  7987.                 @publisher_db = @publisher_db,
  7988.                 @publication = @publication,
  7989.                 @subscriber_id = @subscriber_id,
  7990.                 @subscriber_db = @subscriber_db,
  7991.                 @subscription_type = @subscription_type,
  7992.                 @local_job = @local_job,
  7993.                 @agent_id = @agent_id OUTPUT,
  7994.                 @distribution_jobid = @distribution_jobid OUTPUT,
  7995.                 @update_mode = @update_mode,
  7996.                 @offloadagent = @offloadagent,
  7997.                 @offloadserver = @offloadserver 
  7998.                 
  7999.                 -- Only push has distributor side package.
  8000.  
  8001.             if @@error <> 0 or @retcode <> 0
  8002.                 goto UNDO
  8003.         end
  8004.  
  8005.         if @subscriber_id = @virtual
  8006.         begin
  8007.             execute @retcode = dbo.sp_MSadd_distribution_agent
  8008.                 @publisher_id = @publisher_id,
  8009.                 @publisher_db = @publisher_db,
  8010.                 @publication = @publication,
  8011.                 @subscriber_id = @virtual_anonymous,
  8012.                 @subscriber_db = @subscriber_db,
  8013.                 @subscription_type = @subscription_type,
  8014.                 @local_job = @local_job,
  8015.                 @agent_id = @anonymous_agent_id OUTPUT,
  8016.                 @distribution_jobid = @distribution_jobid OUTPUT,
  8017.                 @update_mode = @update_mode
  8018.                 -- No need to specify offload parameters for virtual agents
  8019.                 -- No need to specify package name for virtual agents
  8020.         end
  8021.     end
  8022.  
  8023.     insert into MSsubscriptions values (@publisher_database_id, @publisher_id, @publisher_db, @publication_id,
  8024.         @article_id, @subscriber_id, @subscriber_db, @subscription_type, @sync_type, @status, 
  8025.         @subscription_seqno, @snapshot_seqno_flag, @independent_agent, getdate(), 
  8026.         -- synctran
  8027.         @loopback_detection, @agent_id, @update_mode, @subscription_seqno, @subscription_seqno)
  8028.     if @@error <> 0
  8029.         goto UNDO
  8030.  
  8031.     -- For shiloh, always add virtual anonymous entry for attach logic
  8032.     -- If anonymous publication, add "virtual anonymous" subscription
  8033.     -- when adding the virtual subscription
  8034.     if @subscriber_id = @virtual
  8035.     begin
  8036.         insert into MSsubscriptions values (@publisher_database_id, @publisher_id, @publisher_db, @publication_id,
  8037.             @article_id, @virtual_anonymous, @subscriber_db, @subscription_type, @sync_type, @status, 
  8038.             @subscription_seqno, @snapshot_seqno_flag, @independent_agent, getdate(), 
  8039.             -- synctran
  8040.             @loopback_detection, @anonymous_agent_id, @update_mode, @subscription_seqno, @subscription_seqno)
  8041.         if @@error <> 0
  8042.             goto UNDO
  8043.     end
  8044.  
  8045.     -- Check to see if we need to add a new qreader agent
  8046.     if (@update_mode in (2,3,4,5))
  8047.     begin
  8048.         --
  8049.         -- we can have only one agent for the distribution database
  8050.         --
  8051.         if not exists (select * from dbo.MSqreader_agents) 
  8052.         begin
  8053.             execute @retcode = dbo.sp_MSadd_qreader_agent
  8054.             if (@retcode != 0 or @@error != 0)
  8055.                 goto UNDO
  8056.         end
  8057.     end
  8058.     
  8059.     commit transaction
  8060.  
  8061.     --  Add dummy distribution aent row entry for publication.  This will allow the status
  8062.     --  for the shared distribution agent to be restricted
  8063.     if @publication_name IS NOT NULL
  8064.     begin
  8065.         select @agent_name = name from MSdistribution_agents where id = @agent_id
  8066.  
  8067.         if @agent_name IS NOT NULL
  8068.             EXEC dbo.sp_MSupdate_replication_status
  8069.                 @publisher,
  8070.                 @publisher_db,
  8071.                 @publication_name, 
  8072.                 @agent_type = 3,   
  8073.                 @agent_name = @agent_name, 
  8074.                 @status = -3    -- Use current agent_status
  8075.     end
  8076.  
  8077.     -- Refresh global status table. 
  8078.     EXEC dbo.sp_MSupdate_replication_status
  8079.         @publisher,
  8080.         @publisher_db,
  8081.         @publication = '%',    -- refresh the publisher node.
  8082.         @agent_type = NULL,    -- Not used    with @status = -2
  8083.         @agent_name = NULL, -- Not used with @status = -2
  8084.         @status = -2    -- refresh status
  8085.  
  8086.     return(0)
  8087.  
  8088. UNDO:
  8089.     if @@TRANCOUNT > 0
  8090.     begin
  8091.         ROLLBACK TRAN MSadd_subscription
  8092.         COMMIT TRAN
  8093.     end
  8094.     return(1)
  8095.  
  8096. GO
  8097.  
  8098. raiserror(15339,-1,-1,'sp_MSupdate_subscription')
  8099. GO
  8100. CREATE PROCEDURE sp_MSupdate_subscription
  8101. @publisher sysname,
  8102. @publisher_db sysname,
  8103. @subscriber sysname,
  8104. @article_id int,
  8105. @status int,
  8106. @subscription_seqno varbinary(16),
  8107. --post 6x
  8108. @destination_db sysname = '%'
  8109.  
  8110. as
  8111.     set nocount on
  8112.     declare @publisher_id smallint  
  8113.     declare @subscriber_id smallint
  8114.     declare @automatic tinyint
  8115.     declare @snapshot_seqno_flag bit
  8116.     declare @virtual smallint 
  8117.     declare @virtual_anonymous smallint 
  8118.     declare @retcode int
  8119.     declare @active tinyint
  8120.     declare @subscribed tinyint
  8121.     declare @agent_id int
  8122.     declare @sync_type tinyint
  8123.     declare @virtual_agent_id int
  8124.     declare @publication_id int
  8125.  
  8126.     select @automatic = 1
  8127.     select @virtual = - 1
  8128.     select @virtual_anonymous = - 2
  8129.     select @active = 2
  8130.     select @subscribed = 1
  8131.  
  8132.     -- Check if publisher is a defined as a distribution publisher in the current database
  8133.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  8134.     if @retcode <> 0
  8135.     begin
  8136.         return(1)
  8137.     end
  8138.  
  8139.     -- Check if subscriber exists
  8140.     if @subscriber is null
  8141.     begin
  8142.         select @subscriber_id = @virtual
  8143.         select @destination_db = '%'
  8144.     end
  8145.     else
  8146.         select @subscriber_id = srvid from master..sysservers, MSsubscriber_info where 
  8147.             UPPER(srvname) = UPPER(@subscriber) and
  8148.             UPPER(subscriber) = UPPER(@subscriber) and
  8149.             UPPER(publisher) = UPPER(@publisher)
  8150.     if @subscriber_id is NULL
  8151.     begin
  8152.         raiserror (20032, 16, -1, @subscriber, @publisher) 
  8153.         return (1)
  8154.     end
  8155.  
  8156.     begin tran
  8157.     save transaction MSupdate_subscription
  8158.  
  8159.     if @status = @active
  8160.     begin
  8161.         -- Activating the subscription
  8162.         /*
  8163.         **  It will be used by:
  8164.         **  1. no_sync subscriptions
  8165.         **  2. subscriptions on immediate_sync pub that are activate 
  8166.         **  using virtual subscritpions's snapshots.
  8167.         **  3. snapshot agents for 6.5 publishers
  8168.         */
  8169.         -- Get agent_id etc
  8170.         select @agent_id = agent_id, @sync_type = sync_type,
  8171.             @publication_id = publication_id
  8172.             from MSsubscriptions where
  8173.             publisher_id = @publisher_id and
  8174.             publisher_db = @publisher_db and
  8175.             article_id = @article_id and
  8176.             subscriber_id = @subscriber_id and 
  8177.             -- Use equal so 6.x publisher will get nothing (since @destination_db is '%')
  8178.             subscriber_db = @destination_db
  8179.  
  8180.         -- If immediate_sync publication and sync type is auto_sync
  8181.         -- Set the subscription_seqno and snapshot_seqno to be of the virtual subscription 
  8182.         -- for real subscription when activating the subscription.
  8183.         -- We have to do it for the whole publication to prevent the
  8184.         -- distribution agent from picking up partial snapshot transaction
  8185.         if  @subscriber IS NOT NULL AND
  8186.             @sync_type = @automatic and
  8187.             exists (select * from MSpublications p where
  8188.                 -- publication_id is unique across dist db
  8189.                 p.publication_id = @publication_id and
  8190.                 p.immediate_sync = 1 
  8191.                 )
  8192.         begin
  8193.             -- Get virtual agent_id
  8194.             select @virtual_agent_id = agent_id from MSsubscriptions where
  8195.                 publisher_id = @publisher_id and
  8196.                 publisher_db = @publisher_db and
  8197.                 article_id = @article_id and
  8198.                 subscriber_id = @virtual
  8199.  
  8200.             -- Note it is possible that the virtual subscriptions
  8201.             -- were deactivated during clean up.
  8202.             /* Update the subscription table for the whole publication */
  8203.             -- Note: You need to change sp_MSreset_subscription_seqno when you 
  8204.             -- change this query
  8205.             update MSsubscriptions  set 
  8206.                 snapshot_seqno_flag =  
  8207.                     (select subscription_seqno from MSsubscriptions rs2
  8208.                         where
  8209.                         rs2.agent_id = @virtual_agent_id and
  8210.                         rs2.article_id = rs1.article_id),
  8211.                 status =    
  8212.                     (select status from MSsubscriptions rs2
  8213.                         where
  8214.                         rs2.agent_id = @virtual_agent_id and
  8215.                         rs2.article_id = rs1.article_id),
  8216.                 -- Use current date rather than virtual sub date for the
  8217.                 -- calculation in cleanup 
  8218.                 subscription_time = getdate(),
  8219.                 subscription_seqno = 
  8220.                     (select subscription_seqno from MSsubscriptions rs2
  8221.                         where
  8222.                         rs2.agent_id = @virtual_agent_id and
  8223.                         rs2.article_id = rs1.article_id),
  8224.                 publisher_seqno = 
  8225.                     (select publisher_seqno from MSsubscriptions rs2
  8226.                         where
  8227.                         rs2.agent_id = @virtual_agent_id and
  8228.                         rs2.article_id = rs1.article_id),
  8229.                 ss_cplt_seqno = 
  8230.                     (select ss_cplt_seqno from MSsubscriptions rs2
  8231.                         where
  8232.                         rs2.agent_id = @virtual_agent_id and
  8233.                         rs2.article_id = rs1.article_id)
  8234.                 from MSsubscriptions rs1 where
  8235.                     agent_id = @agent_id and
  8236.                     sync_type = @automatic and
  8237.                     status = @subscribed            
  8238.             if @@ERROR <> 0
  8239.                 goto UNDO
  8240.         end
  8241.         else
  8242.         begin
  8243.             update MSsubscriptions set status = @status, subscription_time = getdate(), 
  8244.                 publisher_seqno = @subscription_seqno, ss_cplt_seqno = @subscription_seqno,
  8245.                 -- Have to do this. Refer to anonymous agent "no init sync" option logic above
  8246.                 -- and sp_MSset_snapshot_seqno.
  8247.                 snapshot_seqno_flag = 0 
  8248.                 where
  8249.                   publisher_id = @publisher_id and
  8250.                   publisher_db = @publisher_db and
  8251.                   article_id = @article_id and
  8252.                   ((@subscriber_id <> @virtual and (subscriber_id = @subscriber_id and ((@destination_db = N'%') or (subscriber_db = @destination_db)) )) or
  8253.                   -- Activate virtual_anonymous but NOT virtual
  8254.                   -- This is for no init option for anonymous agent
  8255.                   -- Refer to sp_addsubscription , sp_MSget_repl_cmds_anonymous
  8256.                   -- and sp_MSset_snapshot_seqno
  8257.                   (@subscriber_id =  @virtual and subscriber_id = @virtual_anonymous))
  8258.             if @@error <> 0
  8259.                 goto UNDO
  8260.         
  8261.             -- For 6.5 publishers.
  8262.             -- Snapshot agents of 6.5 publishers will call sp_changesubstatus which will
  8263.             -- RPC this stored procedure to activate the subscription. The RPC calls are
  8264.             -- not in one transaction.
  8265.             -- We have to do it for the whole publication to prevent the
  8266.             -- distribution agent from picking up partial snapshot transaction
  8267.  
  8268.             -- Get publication_id 
  8269.             -- The publication_id and sync type are set by SNAPSHOT agent 
  8270.             -- calling sp_MSset_snapshot_xact_seqno
  8271.             -- Don't do it if @subscriber_id is virtual to prevent virtual sub
  8272.             -- to be activated.
  8273.             if @destination_db = '%' and @subscriber_id <> @virtual
  8274.             begin
  8275.                 declare @publication_id_6x int
  8276.                 -- Get the publication_id.
  8277.                 -- Note that if the sync_type is not automatic, the publication_id
  8278.                 -- will be null. In this case, we will not do the later
  8279.                 -- update (we don't need to)
  8280.                 select top 1 @publication_id_6x = publication_id from MSsubscriptions 
  8281.                     where   publisher_id = @publisher_id and
  8282.                             publisher_db = @publisher_db and
  8283.                             subscriber_id = @subscriber_id and 
  8284.                             sync_type = @automatic and
  8285.                             article_id = @article_id
  8286.  
  8287.                 if @publication_id_6x <> NULL
  8288.                 begin
  8289.                     update MSsubscriptions set status = @status, subscription_time = getdate() 
  8290.                         where
  8291.                           publisher_id = @publisher_id and
  8292.                           publisher_db = @publisher_db and
  8293.                           subscriber_id = @subscriber_id and 
  8294.                           sync_type = @automatic and
  8295.                           publication_id = @publication_id_6x and
  8296.                           status <> @status
  8297.                     if @@error <> 0
  8298.                         goto UNDO
  8299.                 end
  8300.             end
  8301.         end
  8302.     end -- End activating the subscription
  8303.     else
  8304.     begin -- Deactivating the subscription or change it from 'subscribed' to 'initiated'
  8305.         /*
  8306.         **  If @status is @active, it will be used by:
  8307.         **  sp_reinitsubscription at publisher to reset the subscription status to 'subscribed'
  8308.         **  If @status is @initiated (2), it will be used by snapshot agent with 
  8309.         **  sp_MSactivate_auto_sub => sp_changesubstatus.
  8310.         */
  8311.         update MSsubscriptions set status = @status, 
  8312.                                    publisher_seqno = @subscription_seqno, 
  8313.                                    ss_cplt_seqno = @subscription_seqno
  8314.             where
  8315.             publisher_id = @publisher_id and
  8316.             publisher_db = @publisher_db and
  8317.             article_id = @article_id and
  8318.             ((@subscriber_id <> @virtual and (subscriber_id = @subscriber_id and ((@destination_db = N'%') or (subscriber_db = @destination_db)) )) or
  8319.             -- Deactivating both virtual and virtual anonymous
  8320.             (@subscriber_id =  @virtual and (subscriber_id = @virtual or (subscriber_id = @virtual_anonymous and
  8321.             -- When changing to @initiated, do not change activated virtual_anonymous_subscription.
  8322.             (@status = @subscribed or snapshot_seqno_flag = 0)))))
  8323.  
  8324.         if @@error <> 0
  8325.             goto UNDO
  8326.     end
  8327.  
  8328.     
  8329.     commit transaction
  8330.     return (0)
  8331.  
  8332. UNDO:
  8333.     if @@TRANCOUNT > 0
  8334.     begin
  8335.         ROLLBACK TRAN MSupdate_subscription
  8336.         COMMIT TRAN
  8337.     end
  8338.     return(1)
  8339. GO
  8340.  
  8341.  
  8342. declare @dbname sysname
  8343. select  @dbname = db_name()
  8344. execute('dump transaction ' +@dbname+ ' with no_log')
  8345.  
  8346. go
  8347.  
  8348. /*
  8349. **  Note: sp_MSget_repl_commands and sp_MSget_repl_count have very similar
  8350. **  queries. Any changes to one of them should be applied to all others.
  8351. */
  8352.  
  8353. raiserror(15339,-1,-1,'sp_MSget_repl_commands')
  8354. GO
  8355. CREATE PROCEDURE sp_MSget_repl_commands
  8356. @agent_id int,
  8357. @last_xact_seqno varbinary(16),
  8358. @get_count bit = 0,
  8359. @compatibility_level int = 7000000
  8360. as
  8361.  
  8362.     set nocount on
  8363.  
  8364.     declare @active_status tinyint
  8365.     declare @initiate_status tinyint
  8366.     declare @snapshot_bit int
  8367.     declare @synctran_type int
  8368.     declare @read_only tinyint
  8369.     declare @retcode int
  8370.     declare @publisher_database_id int
  8371.     declare @originator_id int
  8372.     declare @subscriber sysname
  8373.     declare @subscriber_db sysname
  8374.     declare @subscriber_id smallint
  8375.     declare @publisher_db sysname
  8376.     declare @publisher_id smallint
  8377.     declare @max_xact_seqno varbinary(16)
  8378.     declare @concurrent int
  8379.     declare @concurrent_c int
  8380.  
  8381.     select @read_only = 0
  8382.     select @active_status = 2
  8383.     select @initiate_status = 3
  8384.     select @snapshot_bit = 0x80000000
  8385.     -- in sqlrepl.h
  8386.     select @synctran_type = @snapshot_bit | 9
  8387.     select @concurrent = 3
  8388.     select @concurrent_c = 4
  8389.  
  8390.     -- Security Check
  8391.     -- @agent_id might be null when it comes from sp_MSget_repl_cmd_anonymous
  8392.     if @agent_id is not null
  8393.     begin
  8394.         exec @retcode = dbo.sp_MScheck_pull_access
  8395.             @agent_id = @agent_id,
  8396.             @agent_type = 0 -- distribution agent
  8397.         if @@error <> 0 or @retcode <> 0
  8398.             return (1)
  8399.     end
  8400.     
  8401.     -- Get publisher database id etc.
  8402.     SELECT @publisher_database_id = publisher_database_id,
  8403.         @publisher_db = publisher_db,
  8404.         @publisher_id = publisher_id,
  8405.         @subscriber_id = subscriber_id, @subscriber_db = subscriber_db
  8406.         from MSdistribution_agents where id = @agent_id
  8407.  
  8408.     -- Get the last xact_seqno on the pub db FIRST. It will
  8409.     -- be used as the upper bound for differnt queries. We have to do
  8410.     -- this to prevent transactions on new or changed subscriptions or
  8411.     -- with new orignator_id being skipped eigher by preselected query or
  8412.     -- preselected originator_id.
  8413.     -- Have to have readpast here to prevent the query be blocked by logreader
  8414.     -- (even before the first row to the dist agent).
  8415.     --
  8416.     -- Note:  DO NOT consider distcmds inserted for a concurrent snapshot
  8417.     -- These represent 'forward in time' xacts.  Skipping past these xacts
  8418.     -- can cause lost transactions!
  8419.     --
  8420.     -- Note2: consider adding new MSrepl_commands idx with keys:  
  8421.     -- publisher_database_id, command_id, type, xact_seqno
  8422.     --
  8423.     -- Note3: might be able to use replpostcmd + a LSN mapping token to 
  8424.     -- allow SS agent to post sync cmds to log instead of dist db.
  8425.     --
  8426.     select @max_xact_seqno = max(xact_seqno) from MSrepl_commands (READPAST)
  8427.       where 
  8428.          publisher_database_id = @publisher_database_id and
  8429.          command_id = 1 and
  8430.          type <> -2147483611
  8431.  
  8432.     -- If there's nothing to do, return here to avoid more queries.
  8433.     if @max_xact_seqno = @last_xact_seqno
  8434.     begin
  8435.         if @get_count = 1
  8436.         begin
  8437.             select 
  8438.                 'undelivered_commands' = convert(int, 0), 
  8439.                 'undelivered_transactions' = convert(int, 0) 
  8440.         end
  8441.         else
  8442.         begin
  8443.             select rc.xact_seqno, rc.partial_command, rc.type, 
  8444.                 rc.command_id, rc.command
  8445.                 from                
  8446.                     MSrepl_commands rc
  8447.                 where 0 = 1
  8448.             select @max_xact_seqno
  8449.         end
  8450.         return 0
  8451.     end
  8452.  
  8453.     -- Get subscriber name
  8454.     select @subscriber = srvname from master..sysservers where
  8455.         srvid = @subscriber_id
  8456.         
  8457.     -- Note: if no originator id in the table, it will be 0, so that no loop back
  8458.     -- detection will be done!.
  8459.     -- Since the logreader will insert into the MSrepl_originators table,
  8460.     -- this query has to be later then get max seqno query!!!!!
  8461.     --select @originator_id = 0
  8462.     select @originator_id = ISNULL(id, 0) from MSrepl_originators where
  8463.         publisher_database_id = @publisher_database_id and
  8464.         UPPER(srvname) = UPPER(@subscriber) and
  8465.         dbname = @subscriber_db
  8466.  
  8467.     if @get_count = 1
  8468.     begin
  8469.         select 
  8470.             'undelivered_commands' = count(*), 
  8471.             'undelivered_transactions' = count(distinct xact_seqno) from
  8472.  
  8473.         MSrepl_commands rc JOIN MSsubscriptions s
  8474.         ON (rc.article_id = s.article_id AND rc.publisher_database_id=s.publisher_database_id )
  8475.         
  8476.         where
  8477.  
  8478.         s.agent_id = @agent_id and
  8479.         s.status = @active_status and
  8480.         rc.publisher_database_id = @publisher_database_id and
  8481.         s.publisher_database_id = @publisher_database_id and
  8482.         rc.xact_seqno > @last_xact_seqno and
  8483.         rc.xact_seqno <= @max_xact_seqno and
  8484.         -- If log based transaction, we do
  8485.         -- 1. only select tran later than sub pub seqno
  8486.         -- 2. loopback detection
  8487.         (((rc.type & @snapshot_bit) <> @snapshot_bit and
  8488.         rc.xact_seqno > s.publisher_seqno and
  8489.         rc.xact_seqno > s.ss_cplt_seqno and
  8490.         --
  8491.         -- Loopback detection
  8492.         --
  8493.         (s.loopback_detection = 0 or
  8494.             (@originator_id != 0 and rc.originator_id <> @originator_id))) or 
  8495.         -- If snapshot transaction, we do
  8496.         -- 1. filter out the  snapshot transactions that were inserted later that is not
  8497.         -- the subscription's snapshot transaction
  8498.         -- 2. filter out trigger generation command for non synctran subscription.
  8499.         -- Note: don't do loop back detection.
  8500.         ((rc.type & @snapshot_bit) = @snapshot_bit and 
  8501.         rc.xact_seqno >= s.subscription_seqno and 
  8502.         rc.xact_seqno <= s.ss_cplt_seqno and
  8503.         (s.update_mode <> @read_only or rc.type <> @synctran_type))) and
  8504.         -- Filter out the new command types that we have introduced after 7.0
  8505.         (@compatibility_level > 7000000 or
  8506.         (rc.type & ~@snapshot_bit) not in 
  8507.         (25, 40, 45, 50, 51, 52, 53, 54, 55, 56 ,57, 58, 68, 69))
  8508.                 
  8509.         return(0)
  8510.     end
  8511.  
  8512.     -- if this agent is servicing any inactive concurrent sync articles
  8513.     -- then return no rows.  The concurrent sync article will be activated
  8514.     -- when the SYNCDONE token is written to the distribution db by the logreader
  8515.     -- at this point, all log records associated with the sync will be present in 
  8516.     -- MSrepl_commands
  8517.  
  8518.     if exists( SELECT * FROM MSsubscriptions s JOIN MSpublications p 
  8519.                ON(  s.publisher_id = p.publisher_id and
  8520.                     s.publisher_db = p.publisher_db and
  8521.                     s.publication_id = p.publication_id )
  8522.                WHERE
  8523.                 s.agent_id = @agent_id and
  8524.                 s.status = @initiate_status and
  8525.                 (p.sync_method = @concurrent or p.sync_method = @concurrent_c) )
  8526.     begin
  8527.         select rc.xact_seqno, rc.partial_command, rc.type, 
  8528.             rc.command_id, rc.command
  8529.             from                
  8530.                 MSrepl_commands rc
  8531.             where 0 = 1
  8532.         select @last_xact_seqno
  8533.         return 0
  8534.     end
  8535.  
  8536.     -- Decide on a best query method.
  8537.     -- Note: The order of the following queries is important and
  8538.     -- not abitrary.
  8539.     
  8540.     -- Get subscription info
  8541.     declare @num_non_active int
  8542.     declare @num_article int
  8543.     declare @num_loopback int
  8544.     declare @max_sub_seqno varbinary(16)
  8545.     declare @max_pub_seqno varbinary(16)
  8546.  
  8547.  
  8548.     select 
  8549.         @num_non_active = sum(case when status <> @active_status then 1 else 0 end),
  8550.         @num_article = count(*),
  8551.         @num_loopback   = sum(case when loopback_detection <> 0 then 1 else 0 end),
  8552.         @max_sub_seqno  = max(subscription_seqno),
  8553.         @max_pub_seqno = max(publisher_seqno)
  8554.         from MSsubscriptions where
  8555.             agent_id = @agent_id
  8556.  
  8557.     --select @num_non_active, @num_loopback, @max_sub_seqno
  8558.     
  8559.     if  @last_xact_seqno < @max_sub_seqno or  
  8560.         @last_xact_seqno < @max_pub_seqno or 
  8561.         @num_non_active <> 0
  8562.     -- The agent is still working on snapshot transactions. Need a full join in this case
  8563.     begin
  8564.  
  8565.         -- Need a work table to remember the set of snapshot transaction 
  8566.         -- sequence numbers that need to be applied by this agent, this 
  8567.         -- table of subscription sequence numbers can then be used to make 
  8568.         -- sure that snapshot control (header/trailer) commands associated with 
  8569.         -- incremental snapshot commands are enumerated
  8570.         declare @snapshot_seqnos table (subscription_seqno varchar(16) primary key)
  8571.         insert into @snapshot_seqnos 
  8572.         select distinct subscription_seqno
  8573.           from MSsubscriptions
  8574.          where agent_id = @agent_id 
  8575.            and subscription_seqno > @last_xact_seqno
  8576.            and (subscription_seqno < @max_sub_seqno 
  8577.             or subscription_seqno < @max_pub_seqno)  
  8578.  
  8579.         -- no loopback    
  8580.         if @originator_id = 0
  8581.         begin
  8582.             -- Join with every thing but no loop back
  8583.             select rc.xact_seqno, rc.partial_command, rc.type, 
  8584.                 rc.command_id, rc.command
  8585.                 from                
  8586.                     MSrepl_commands rc JOIN MSsubscriptions s
  8587.                 -- At end, we use the FASTFIRSTROW option which tends to force
  8588.                 -- a nested inner loop join driven from MSrepl_commands
  8589.                 ON (rc.article_id = s.article_id AND rc.publisher_database_id=s.publisher_database_id )
  8590.                 
  8591.                 where
  8592.  
  8593.                 s.agent_id = @agent_id and
  8594.                 s.status = @active_status and
  8595.                 rc.publisher_database_id = @publisher_database_id and
  8596.                 s.publisher_database_id = @publisher_database_id and
  8597.                 rc.xact_seqno > @last_xact_seqno and
  8598.                 rc.xact_seqno <= @max_xact_seqno and
  8599.                 -- If log based transaction, we do
  8600.                 -- 1. only select tran later than sub pub seqno
  8601.                 -- 2. only select tran later than ss_cplt_seqno 
  8602.                 (((rc.type & @snapshot_bit) <> @snapshot_bit and
  8603.                 rc.xact_seqno > s.publisher_seqno and
  8604.                 rc.xact_seqno > s.ss_cplt_seqno ) 
  8605.                 or 
  8606.                 -- If snapshot transaction, we do
  8607.                 -- 1. filter out the  snapshot transactions that were inserted later that is not
  8608.                 -- the subscription's snapshot transaction
  8609.                 -- 2. filter out trigger generation command for non synctran subscription.
  8610.                 -- Note: don't do loop back detection.
  8611.                 ((rc.type & @snapshot_bit) = @snapshot_bit and 
  8612.                 ((rc.xact_seqno >= s.subscription_seqno and 
  8613.                   rc.xact_seqno <= s.ss_cplt_seqno) or
  8614.                  (rc.xact_seqno in (select subscription_seqno from @snapshot_seqnos) and (rc.type & ~@snapshot_bit) in (25, 50, 51, 52, 53, 54, 55, 56 ,57, 58))) and
  8615.                 (s.update_mode <> @read_only or rc.type <> @synctran_type))) and
  8616.                 -- Filter out the new command types that we have introduced after 7.0
  8617.                 (@compatibility_level > 7000000 or
  8618.                 (rc.type & ~@snapshot_bit) not in 
  8619.                 (25, 40, 45, 50, 51, 52, 53, 54, 55, 56 ,57, 58, 68, 69))
  8620.                 order by rc.xact_seqno, rc.command_id asc
  8621.                 OPTION (FAST 1)
  8622.         end
  8623.         else
  8624.         begin
  8625.             -- Join with every thing with loop back
  8626.             select rc.xact_seqno, rc.partial_command, rc.type, 
  8627.                 rc.command_id, rc.command
  8628.                 from                
  8629.                     MSrepl_commands rc JOIN MSsubscriptions s
  8630.                 -- At end, we use the FASTFIRSTROW option which tends to force
  8631.                 -- a nested inner loop join driven from MSrepl_commands
  8632.                 ON (rc.article_id = s.article_id AND rc.publisher_database_id=s.publisher_database_id )
  8633.                 
  8634.                 where
  8635.  
  8636.                 s.agent_id = @agent_id and
  8637.                 s.status = @active_status and
  8638.                 rc.publisher_database_id = @publisher_database_id and
  8639.                 s.publisher_database_id = @publisher_database_id and
  8640.                 rc.xact_seqno > @last_xact_seqno and
  8641.                 rc.xact_seqno <= @max_xact_seqno and
  8642.                 -- If log based transaction, we do
  8643.                 -- 1. only select tran later than sub pub seqno
  8644.                 -- 2. loopback detection
  8645.                 (((rc.type & @snapshot_bit) <> @snapshot_bit and
  8646.                 rc.xact_seqno > s.publisher_seqno and
  8647.                 rc.xact_seqno > s.ss_cplt_seqno and
  8648.                 --
  8649.                 -- Loopback detection
  8650.                 --
  8651.                 (s.loopback_detection = 0 or
  8652.                     rc.originator_id <> @originator_id)) or 
  8653.                 -- If snapshot transaction, we do
  8654.                 -- 1. filter out the  snapshot transactions that were inserted later that is not
  8655.                 -- the subscription's snapshot transaction
  8656.                 -- 2. filter out trigger generation command for non synctran subscription.
  8657.                 -- Note: don't do loop back detection.
  8658.                 ((rc.type & @snapshot_bit) = @snapshot_bit and 
  8659.                 ((rc.xact_seqno >= s.subscription_seqno and 
  8660.                   rc.xact_seqno <= s.ss_cplt_seqno) or
  8661.                  (rc.xact_seqno in (select subscription_seqno from @snapshot_seqnos) and (rc.type & ~@snapshot_bit) in (25, 50, 51, 52, 53, 54, 55, 56 ,57, 58))) and
  8662.                 (s.update_mode <> @read_only or rc.type <> @synctran_type))) and
  8663.                 -- Filter out the new command types that we have introduced after 7.0
  8664.                 (@compatibility_level > 7000000 or
  8665.                 (rc.type & ~@snapshot_bit) not in 
  8666.                 (25, 40, 45, 50, 51, 52, 53, 54, 55, 56 ,57, 58, 68, 69))
  8667.                 order by rc.xact_seqno, rc.command_id asc
  8668.                 OPTION (FAST 1)
  8669.             end
  8670.     end
  8671.     -- The agent has finished snapshot transactions but it has loopback detection.
  8672.     else if @num_loopback <> 0 and @originator_id <> 0
  8673.     begin
  8674.         -- Join plus loopback
  8675.         select rc.xact_seqno, rc.partial_command, rc.type, 
  8676.             rc.command_id, rc.command
  8677.             from                
  8678.                 MSrepl_commands rc JOIN MSsubscriptions s
  8679.             -- At end, we use the FASTFIRSTROW option which tends to force
  8680.             -- a nested inner loop join driven from MSrepl_commands
  8681.             ON (rc.article_id = s.article_id)
  8682.             
  8683.             where
  8684.  
  8685.             s.agent_id = @agent_id and
  8686.             rc.publisher_database_id = @publisher_database_id and
  8687.             rc.xact_seqno > @last_xact_seqno and
  8688.             rc.xact_seqno <= @max_xact_seqno and
  8689.             (rc.type & @snapshot_bit) <> @snapshot_bit and
  8690.             (rc.type & ~@snapshot_bit) not in ( 37, 38 ) and
  8691.             --
  8692.             -- Loopback detection
  8693.             --
  8694.             (s.loopback_detection = 0 or
  8695.             rc.originator_id <> @originator_id) 
  8696.             order by rc.xact_seqno, rc.command_id asc
  8697.             OPTION (FAST 1)
  8698.     end
  8699.     -- The agent has finished snapshot transactions. It has NO loopback detection.
  8700.     else if @num_article <> (select count(*) from MSarticles  a where
  8701.         publisher_id = @publisher_id and
  8702.         publisher_db = @publisher_db)
  8703.     -- Not a full subscription, do mini join
  8704.     begin
  8705.         -- Mini join along. Only agent_id and article_id columns in MSsubscriptions
  8706.         -- are used. So only index pages are needed for the join.
  8707.         select rc.xact_seqno, rc.partial_command, rc.type, 
  8708.         rc.command_id, rc.command
  8709.         from                
  8710.             MSrepl_commands rc JOIN MSsubscriptions s
  8711.         -- At end, we use the FASTFIRSTROW option which tends to force
  8712.         -- a nested inner loop join driven from MSrepl_commands
  8713.         ON (rc.article_id = s.article_id)
  8714.         where
  8715.         s.agent_id = @agent_id and
  8716.         rc.publisher_database_id = @publisher_database_id and
  8717.         rc.xact_seqno > @last_xact_seqno and
  8718.         rc.xact_seqno <= @max_xact_seqno and
  8719.         (rc.type & @snapshot_bit) <> @snapshot_bit and
  8720.         (rc.type & ~@snapshot_bit) not in ( 37, 38 ) 
  8721.         order by rc.xact_seqno, rc.command_id asc
  8722.         OPTION (FAST 1)
  8723.     end
  8724.     else
  8725.     -- The query will fly if we reach here!! No join is needed.
  8726.     -- It is a full sub to pub db, the dist agent is beyond snapshots, 
  8727.     -- all sub are active and no loopback detection. 
  8728.     begin
  8729.         -- no join.
  8730.         select rc.xact_seqno, rc.partial_command, rc.type, 
  8731.         rc.command_id, rc.command
  8732.         from                
  8733.             MSrepl_commands rc 
  8734.         where
  8735.         rc.publisher_database_id = @publisher_database_id and
  8736.         rc.xact_seqno > @last_xact_seqno and
  8737.         rc.xact_seqno <= @max_xact_seqno and
  8738.         (rc.type & @snapshot_bit) <> @snapshot_bit and
  8739.         (rc.type & ~@snapshot_bit) not in ( 37, 38 ) 
  8740.         order by rc.xact_seqno, rc.command_id asc
  8741.     end 
  8742.  
  8743.     -- Return the max seqno of this batch to distribution agent.
  8744.     select @max_xact_seqno
  8745.  
  8746. GO
  8747.  
  8748.  
  8749.  
  8750. raiserror(15339,-1,-1,'sp_MSget_repl_cmds_anonymous')
  8751. GO
  8752. CREATE PROCEDURE sp_MSget_repl_cmds_anonymous
  8753. @agent_id int,
  8754. @last_xact_seqno varbinary(16),
  8755. @no_init_sync bit = 0,
  8756. @get_count bit = 0,
  8757. @compatibility_level int = 7000000
  8758.  
  8759. as
  8760.  
  8761.    set nocount on
  8762.  
  8763.    declare @virtual_agent_id int    /* virtual sub agent id */
  8764.    declare @anonymous_agent_id int  /* virtual anonymous agent id */
  8765.  
  8766.     -- Note @agent_id will be overwritten later.
  8767.     select  @virtual_agent_id =   virtual_agent_id,
  8768.             @anonymous_agent_id = anonymous_agent_id
  8769.         from MSdistribution_agents where
  8770.             id = @agent_id
  8771.     
  8772.     -- Return error if agent entry does not exists (being deleted).
  8773.     if @virtual_agent_id is null
  8774.     begin
  8775.         raiserror(21072, 16, -1)
  8776.         return(1)
  8777.     end
  8778.  
  8779.     -- If no init sync, use anonymous account to start immediately.
  8780.     -- If first time or right after reinit,  use virtual account. 
  8781.     -- otherwise use virtual anonymous account
  8782.     if  @no_init_sync = 1 
  8783.         select @agent_id = @anonymous_agent_id
  8784.     else if @last_xact_seqno = 0x00 
  8785.         select @agent_id = @virtual_agent_id
  8786.     else
  8787.         select @agent_id = @anonymous_agent_id
  8788.     -- Call main procedure to get commands
  8789.     exec dbo.sp_MSget_repl_commands 
  8790.         @agent_id = @agent_id,
  8791.         @last_xact_seqno = @last_xact_seqno,
  8792.         @get_count = @get_count,
  8793.         @compatibility_level = @compatibility_level
  8794. GO
  8795.  
  8796.  
  8797.  
  8798. raiserror(15339,-1,-1,'sp_MSanonymous_status')
  8799. GO
  8800. CREATE PROCEDURE sp_MSanonymous_status
  8801. @agent_id           int,
  8802. @no_init_sync       int = 0,
  8803. @last_xact_seqno varbinary(16)
  8804. as
  8805.  
  8806.    set nocount on
  8807.  
  8808.    declare @virtual_agent_id int    /* virtual sub agent id */
  8809.    declare @anonymous_agent_id int  /* virtual anonymous agent id */
  8810.  
  8811.     -- Note @agent_id will be overwritten later.
  8812.     select  @virtual_agent_id =   virtual_agent_id,
  8813.             @anonymous_agent_id = anonymous_agent_id
  8814.         from MSdistribution_agents where
  8815.             id = @agent_id
  8816.     
  8817.     -- Return error if agent entry does not exists (being deleted).
  8818.     if @virtual_agent_id is null
  8819.     begin
  8820.         raiserror(21072, 16, -1)
  8821.         return(1)
  8822.     end
  8823.  
  8824.     -- If no init sync, use anonymous account to start immediately.
  8825.     -- If first time, or still working on the first snapshot, or just finished
  8826.     -- the first snapshot, use virtual account. This is to cover the case
  8827.     -- of multiple snapshot transactions (for example, one per article) in the first
  8828.     -- snapshot.
  8829.     -- otherwise use virtual anonymous account
  8830.     if  @no_init_sync = 1 
  8831.         select @agent_id = @anonymous_agent_id
  8832.     else if @last_xact_seqno = 0x00 
  8833.         select @agent_id = @virtual_agent_id
  8834.     else
  8835.         select @agent_id = @anonymous_agent_id
  8836.     
  8837.     -- Call main procedure to get status
  8838.     exec dbo.sp_MSsubscription_status
  8839.         @agent_id = @agent_id
  8840. GO
  8841.  
  8842. raiserror(15339,-1,-1,'sp_MSadd_anonymous_agent')
  8843. GO
  8844. CREATE PROCEDURE sp_MSadd_anonymous_agent
  8845. @publisher_id       smallint,
  8846. @publisher_db       sysname,
  8847. @publication        sysname,
  8848. @subscriber_db      sysname,
  8849. @subscriber_name    sysname,
  8850. @anonymous_subid    uniqueidentifier output,
  8851. @agent_id           int output,
  8852. @reinitanon         bit = 0
  8853.  
  8854. as
  8855.  
  8856. /*
  8857. ** This stored procedure does not really add a job at distribution database;
  8858. ** if add a row in MSdistribution_agent table for anonymous subscription for the 
  8859. ** purpose of history logging
  8860. */
  8861.  
  8862.    set nocount on
  8863.    declare @distribution_type smallint
  8864.    declare @profile_id int
  8865.    declare @subscriber_id smallint
  8866.    declare @retcode int
  8867.    declare @publication_id int
  8868.    declare @virtual_agent_id int
  8869.    declare @anonymous_agent_id int
  8870.    declare @virtual smallint
  8871.    declare @virtual_anonymous smallint
  8872.    declare @new_agent_id int
  8873.    declare @anonymous int
  8874.    declare @publisher_database_id int
  8875.    declare @allow_anonymous bit
  8876.    declare @publication_type int
  8877.    declare @merge_publication_type int
  8878.    
  8879.    select @publication_type = NULL
  8880.    select @merge_publication_type = 2
  8881.    
  8882.    select @virtual = -1
  8883.    select @virtual_anonymous = -2
  8884.    select @anonymous = 2
  8885.    
  8886.     -- Check to see if the publication is valid and allow anonymous
  8887.     select @publication_id = publication_id, @allow_anonymous = allow_anonymous, @publication_type = publication_type
  8888.         from MSpublications where
  8889.         publisher_id = @publisher_id and
  8890.         publisher_db = @publisher_db and
  8891.         publication = @publication 
  8892.  
  8893.     if @publication_id is null
  8894.     begin
  8895.         RAISERROR (21040, 16, -1, @publication)
  8896.         return 1
  8897.     end
  8898.  
  8899.     if @publication_type = @merge_publication_type
  8900.     begin
  8901.         RAISERROR(21132, 16, -1, @publication)
  8902.         return 1
  8903.     end
  8904.  
  8905.     if @allow_anonymous = 0
  8906.     begin
  8907.         RAISERROR (21084, 16, -1, @publication)
  8908.         return 1       
  8909.     end
  8910.  
  8911.     if @subscriber_name is null
  8912.         select @subscriber_name = N''
  8913.  
  8914.     -- Get virtual ids
  8915.     select top 1 @virtual_agent_id = agent_id, 
  8916.         @publisher_database_id = publisher_database_id from MSsubscriptions where
  8917.         publisher_id = @publisher_id and
  8918.         publisher_db = @publisher_db and
  8919.         publication_id = @publication_id and
  8920.         subscriber_id = @virtual
  8921.  
  8922.     select top 1 @anonymous_agent_id = agent_id from MSsubscriptions where
  8923.         publisher_id = @publisher_id and
  8924.         publisher_db = @publisher_db and
  8925.         publication_id = @publication_id and
  8926.         subscriber_id = @virtual_anonymous
  8927.  
  8928.  
  8929.     -- Security check
  8930.     exec @retcode = dbo.sp_MScheck_pull_access
  8931.         @agent_id =  @anonymous_agent_id,
  8932.         @agent_type = 0 -- distribution agent   
  8933.     if @retcode <> 0 or @@error <> 0
  8934.         return (1)
  8935.  
  8936.     /*
  8937.     **  To return two more parameters for the purpose of anonymous monitoring
  8938.     ** 
  8939.     ** If @anonymous_subid is null, this is a new anonymous subscription; A new row would be inserted in MSdistribution_agents.
  8940.     ** And its id (identity) and newly generated ID will be returned; The new ID would be used in subscriber side.
  8941.     */
  8942.     select @subscriber_id = 0   -- for anonymous subscribers, ID is always 0
  8943.  
  8944.     select @agent_id = id from MSdistribution_agents 
  8945.         where anonymous_subid = @anonymous_subid
  8946.         
  8947.     
  8948.     IF @agent_id is null
  8949.         BEGIN
  8950.             if @anonymous_subid is not NULL and @anonymous_subid <> 0x00
  8951.                and @reinitanon = 0
  8952.             begin
  8953.                 -- Agent has be cleaned up, return error.
  8954.                 raiserror(21072, 16, -1)
  8955.                 return(1)
  8956.             end
  8957.             -- Generate a new subid only when the subscription is not 
  8958.             -- reinitialized
  8959.             if @reinitanon = 0
  8960.             begin
  8961.                 select @anonymous_subid = newid()
  8962.             end
  8963.             SELECT @distribution_type = 3
  8964.  
  8965.             SELECT @profile_id = profile_id
  8966.             FROM msdb..MSagent_profiles
  8967.             WHERE agent_type = @distribution_type
  8968.                 AND def_profile = 1
  8969.  
  8970.             IF @profile_id IS NULL
  8971.             RETURN (1)
  8972.  
  8973.             INSERT into MSdistribution_agents (name, publisher_database_id, publisher_id, publisher_db, publication, 
  8974.                         subscriber_id, subscriber_db, subscription_type, local_job, job_id, subscription_guid, profile_id, anonymous_subid, 
  8975.                         subscriber_name, virtual_agent_id, anonymous_agent_id)
  8976.                         
  8977.                  VALUES (convert(nvarchar(40), @anonymous_subid), @publisher_database_id, @publisher_id, @publisher_db, @publication, 
  8978.                             @subscriber_id, @subscriber_db, @anonymous, 0, @anonymous_subid,
  8979.                             @anonymous_subid, @profile_id, @anonymous_subid, @subscriber_name,
  8980.                             @virtual_agent_id, @anonymous_agent_id)
  8981.             select @agent_id = @@identity
  8982.         END
  8983.         
  8984. GO
  8985.  
  8986.  
  8987. raiserror(15339,-1,-1,'sp_MSsubscription_status')
  8988. GO
  8989. CREATE PROCEDURE sp_MSsubscription_status
  8990. @agent_id int
  8991. as
  8992.  
  8993.     set nocount on
  8994.  
  8995.     declare @status tinyint
  8996.     declare @inactive tinyint
  8997.     declare @active tinyint
  8998.     declare @subscribed tinyint
  8999.     declare @initiated tinyint
  9000.     declare @article_id int
  9001.     declare @publication sysname
  9002.     declare @article sysname
  9003.     declare @msg nvarchar(255)
  9004.     declare @automatic tinyint
  9005.     declare @none tinyint
  9006.     declare @success int
  9007.     declare @retention int
  9008.     declare @last_sync datetime
  9009.     declare @publication_id int
  9010.  
  9011.     select @success = 2
  9012.     select @inactive = 0
  9013.     select @subscribed = 1
  9014.     select @active = 2
  9015.     select @initiated = 3
  9016.     SELECT @automatic = 1
  9017.     select @none = 2
  9018.  
  9019.     -- If one article is inactive, and no_sync subscription fail.
  9020.     if exists (select * from MSsubscriptions where
  9021.         status = @inactive and
  9022.         sync_type = @none and
  9023.         agent_id = @agent_id)
  9024.     begin
  9025.         -- The subscription was deactivated.
  9026.         raiserror(21074, 16,-1)
  9027.         return(1)
  9028.     end
  9029.     
  9030.     -- If one article is inactive, fail.
  9031.     if exists (select * from MSsubscriptions where
  9032.         status = @inactive and
  9033.         sync_type = @automatic and
  9034.         agent_id = @agent_id)
  9035.     begin
  9036.         -- The subscription was deactivated.
  9037.         raiserror(21074, 16,-1)
  9038.         return(1)
  9039.     end
  9040.  
  9041.     select top 1 @article_id = article_id,
  9042.         @publication_id = publication_id
  9043.         from MSsubscriptions where
  9044.         agent_id = @agent_id and
  9045.         sync_type = @automatic and
  9046.         status = @subscribed
  9047.  
  9048.     if @publication_id is not null
  9049.     begin
  9050.         -- Get the publication name to use later in the formated message
  9051.         select @publication = publication from MSpublications where
  9052.             publication_id = @publication_id
  9053.  
  9054.         -- If there's more than one article in subscribed state
  9055.         -- Send a general waiting message.
  9056.         -- Otherwise, indicate the article name
  9057.         if exists (select * from MSsubscriptions where
  9058.             agent_id = @agent_id and
  9059.             status = @subscribed and
  9060.             sync_type = @automatic and
  9061.             article_id <> @article_id)
  9062.         begin
  9063.             -- Snapshot not available message
  9064.             if @publication is not null
  9065.                 select @msg = formatmessage(21075, @publication)
  9066.             else -- It is null for 6.5
  9067.                 select @msg = formatmessage(21088)
  9068.         end
  9069.         else
  9070.         begin
  9071.             -- article_id is unique across pub db for tran
  9072.             -- but merge article may use the same id
  9073.             select @article = article from MSarticles where
  9074.                 article_id = @article_id and
  9075.                 publication_id = @publication_id
  9076.             -- It is null for 6.5
  9077.             if @article is not null
  9078.                 select @msg = formatmessage(21076, @article)
  9079.             else
  9080.             begin
  9081.                 -- Snapshot not available message
  9082.                 if @publication is not null
  9083.                     select @msg = formatmessage(21075, @publication)
  9084.                 else -- It is null for 6.5
  9085.                     select @msg = formatmessage(21088)
  9086.             end
  9087.         end
  9088.  
  9089.         -- If one article is active, the status is active
  9090.         if exists ( select * from MSsubscriptions where
  9091.             agent_id = @agent_id and
  9092.             sync_type = @automatic and
  9093.             status = @active)
  9094.             set @status = @active
  9095.         else
  9096.             set @status = @subscribed
  9097.     end
  9098.     else
  9099.     -- For concurrent snapshot, logreader has to run first.
  9100.     begin
  9101.          select top 1 @publication_id = publication_id, @status = status from MSsubscriptions s where
  9102.                 s.status = @initiated and
  9103.                 s.agent_id = @agent_id and
  9104.                 s.sync_type = @automatic
  9105.  
  9106.         if @publication_id is not null
  9107.         begin
  9108.             select @publication = publication from MSpublications where
  9109.                 publication_id = @publication_id
  9110.             select @msg = formatmessage(21388, @publication)
  9111.         end
  9112.     end
  9113.  
  9114.     -- If nothing returned, all articles are active.
  9115.     select 'msg' = @msg, 'status' = @status 
  9116.         where @msg is not null
  9117.  
  9118. GO
  9119.  
  9120.  
  9121.  
  9122.  
  9123. raiserror(15339,-1,-1,'sp_MSget_last_transaction')
  9124. GO
  9125. CREATE PROCEDURE sp_MSget_last_transaction
  9126. @publisher_id int = NULL,
  9127. @publisher_db sysname,
  9128. @publisher sysname = NULL,
  9129. @max_xact_seqno varbinary(16) = NULL output
  9130. ,@for_truncate bit = 0
  9131.  
  9132. AS
  9133.     declare @publisher_database_id int
  9134.     declare @max_xact_id varbinary(16)
  9135.     declare @sync_bit int
  9136.     declare @sync_with_backup bit
  9137.     
  9138.     set nocount on 
  9139.     
  9140.     SELECT @sync_bit = 32
  9141.  
  9142.     if @publisher_id is NULL
  9143.         select @publisher_id = srvid from master..sysservers where
  9144.             UPPER(srvname) = UPPER(@publisher)
  9145.  
  9146.     -- Get publisher database id.
  9147.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  9148.         publisher_db = @publisher_db
  9149.     
  9150.     if exists ( select * from master.dbo.sysdatabases where 
  9151.             name = db_name() and
  9152.             category & @sync_bit = 0) 
  9153.         select @sync_with_backup = 0
  9154.     else
  9155.         select @sync_with_backup = 1
  9156.  
  9157.  
  9158.  
  9159.     if @for_truncate = 0
  9160.     begin
  9161.         select top 1 @max_xact_id = rt.xact_id, @max_xact_seqno = rt.xact_seqno
  9162.           from
  9163.           MSrepl_transactions rt
  9164.           where 
  9165.              rt.publisher_database_id = @publisher_database_id and
  9166.              not xact_id = 0x0
  9167.              order by xact_seqno desc
  9168.     end
  9169.     -- If (1) requesting truncate lsn (distbackuplsn), (2) sync with backup is set
  9170.     -- query the values from MSrepl_backup_lsn
  9171.     else if    @sync_with_backup = 1
  9172.     begin
  9173.         -- Get the last backed up lsn if available.
  9174.         select top 1 @max_xact_id = valid_xact_id, @max_xact_seqno = valid_xact_seqno
  9175.           from
  9176.           MSrepl_backup_lsns 
  9177.           where 
  9178.              publisher_database_id = @publisher_database_id 
  9179.     end
  9180.     
  9181.     -- If @publisher is not null, we are calling this sp from sp_replrestart
  9182.     -- Don't return result set.
  9183.     if @publisher is null
  9184.         select @max_xact_id, @max_xact_seqno 
  9185.             -- Don't return any result when requsting a truncate lsn and
  9186.             -- the database is not in 'sync with backup' mode, which signal the 
  9187.             -- distribution agent to use last dist lsn to call sp_repldone.
  9188.             where not (@sync_with_backup = 0 and @for_truncate = 1)
  9189.   
  9190. GO
  9191.  
  9192. raiserror(15339,-1,-1,'sp_MSadd_subscriber_info')
  9193. GO
  9194. CREATE PROCEDURE sp_MSadd_subscriber_info
  9195. @publisher sysname,
  9196. @subscriber sysname,
  9197. @type tinyint = 0,
  9198. @login sysname = 'sa',
  9199. @password nvarchar(524) = NULL,
  9200. @commit_batch_size int = 100,
  9201. @status_batch_size int = 100,
  9202. @flush_frequency int = 0,
  9203. @frequency_type int = 4,
  9204. @frequency_interval int = 1,
  9205. @frequency_relative_interval int = 1,
  9206. @frequency_recurrence_factor int = 0,
  9207. @frequency_subday int = 4,
  9208. @frequency_subday_interval int = 5,
  9209. @active_start_time_of_day int = 0,
  9210. @active_end_time_of_day int = 235959,
  9211. @active_start_date int = 0,
  9212. @active_end_date int = 99991231,
  9213. @retryattempts int = 0,    
  9214. @retrydelay int = 0,
  9215. @description nvarchar (255) = NULL,
  9216. @security_mode int = 1, /* 0 standard; 1 integrated */
  9217. @encrypted_password bit = 0
  9218.  
  9219. AS
  9220.    set nocount on
  9221.  
  9222.    declare @retcode int
  9223.    declare @oledbprovider nvarchar(256)
  9224.    declare @platform_nt binary
  9225.  
  9226.    select @platform_nt = 0x1
  9227.  
  9228.     IF (UPPER(@subscriber) = UPPER(@@SERVERNAME) and ( @platform_nt != platform() & @platform_nt ) and @security_mode = 1)
  9229.         BEGIN
  9230.             RAISERROR(21038, 16, -1)
  9231.             RETURN (1)
  9232.         END
  9233.  
  9234. /* Add the subscriber to sysservers as a RPC server, if it does not
  9235.    ** already exist.
  9236.    */
  9237.    if not exists (select * from  master..sysservers where  UPPER(srvname) = UPPER(@subscriber))
  9238.       begin
  9239.           exec @retcode = dbo.sp_addserver @subscriber
  9240.           if @retcode <> 0
  9241.              return 1
  9242.       end
  9243.    
  9244.     -- Encrypt the password
  9245.     IF @encrypted_password = 0
  9246.     BEGIN
  9247.         EXEC @retcode = master.dbo.xp_repl_encrypt @password OUTPUT
  9248.         IF @@error <> 0 OR @retcode <> 0
  9249.             return 1
  9250.     END
  9251.  
  9252.     if (@type = 3)
  9253.     begin
  9254.         select @oledbprovider = providername from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  9255.         if (@oledbprovider = 'sqloledb')
  9256.             select @security_mode = 1
  9257.         else
  9258.             select @security_mode = 0
  9259.     end
  9260.  
  9261.    /* Delete any existing row */
  9262.    delete from MSsubscriber_info where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  9263.    if @@error <> 0
  9264.      return 1
  9265.    delete from MSsubscriber_schedule where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  9266.    if @@error <> 0
  9267.      return 1
  9268.  
  9269.    begin tran
  9270.    save TRAN addsub_info
  9271.  
  9272.    insert MSsubscriber_info (publisher, subscriber, type, login, password, description, security_mode)
  9273.          values (@publisher, @subscriber, @type, @login, @password, @description, @security_mode)
  9274.     if @@error <> 0
  9275.     goto UNDO
  9276.  
  9277.     /*
  9278.     ** Schedule information is added for backward compartibility reason, agent_type = 0
  9279.     */
  9280.    insert MSsubscriber_schedule values(@publisher, @subscriber, 0, @frequency_type,
  9281.                                         @frequency_interval,
  9282.                                         @frequency_relative_interval,
  9283.                                         @frequency_recurrence_factor ,
  9284.                                         @frequency_subday ,
  9285.                                         @frequency_subday_interval,
  9286.                                         @active_start_time_of_day,
  9287.                                         @active_end_time_of_day ,
  9288.                                         @active_start_date ,
  9289.                                         @active_end_date )
  9290.     if @@error <> 0
  9291.     goto UNDO
  9292.     COMMIT TRAN
  9293.  
  9294.     Return (0)
  9295. UNDO:
  9296.     if @@TRANCOUNT > 0
  9297.     begin
  9298.         ROLLBACK TRAN addsub_info
  9299.         COMMIT TRAN
  9300.     end
  9301.     return (1)
  9302. GO
  9303.  
  9304. raiserror(15339,-1,-1,'sp_MSadd_subscriber_schedule')
  9305. GO
  9306. CREATE PROCEDURE sp_MSadd_subscriber_schedule
  9307. @publisher sysname,
  9308. @subscriber sysname,
  9309. @agent_type smallint = 0,   -- 0 for distribution agent, 1 for merge agent
  9310. @frequency_type int = 4,
  9311. @frequency_interval int = 1,
  9312. @frequency_relative_interval int = 1,
  9313. @frequency_recurrence_factor int = 0,
  9314. @frequency_subday int = 4,
  9315. @frequency_subday_interval int = 5,
  9316. @active_start_time_of_day int = 0,
  9317. @active_end_time_of_day int = 235959,
  9318. @active_start_date int = 0,
  9319. @active_end_date int = 99991231
  9320.  
  9321. AS
  9322.    set nocount on
  9323.  
  9324.    declare @retcode int
  9325.  
  9326.    /* Add the subscriber to sysservers as a RPC server, if it does not
  9327.    ** already exist.
  9328.    */
  9329.    if not exists (select * from  master..sysservers where  UPPER(srvname) = UPPER(@subscriber))
  9330.       begin
  9331.           exec @retcode = dbo.sp_addserver @subscriber
  9332.           if @retcode <> 0
  9333.              return 1
  9334.       end
  9335.  
  9336.    /* Delete any existing row */
  9337.    if exists (select * from MSsubscriber_schedule where
  9338.        UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type=@agent_type)
  9339.        begin
  9340.            delete from MSsubscriber_schedule 
  9341.            where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type=@agent_type
  9342.           if @@error <> 0
  9343.              return 1
  9344.        end
  9345.  
  9346.    insert MSsubscriber_schedule (publisher, subscriber, agent_type, 
  9347.       frequency_type, frequency_interval, frequency_relative_interval,
  9348.       frequency_recurrence_factor, frequency_subday, frequency_subday_interval,
  9349.       active_start_time_of_day, active_end_time_of_day, active_start_date,
  9350.       active_end_date)
  9351.       
  9352.       values (@publisher, @subscriber, @agent_type, 
  9353.       @frequency_type, @frequency_interval, @frequency_relative_interval,
  9354.       @frequency_recurrence_factor, @frequency_subday, @frequency_subday_interval,
  9355.       @active_start_time_of_day, @active_end_time_of_day, @active_start_date,
  9356.       @active_end_date)
  9357.    if @@error <> 0
  9358.       return 1
  9359. GO
  9360.  
  9361.  
  9362.  
  9363. raiserror(15339,-1,-1,'sp_MSupdate_subscriber_info')
  9364. GO
  9365. CREATE PROCEDURE sp_MSupdate_subscriber_info
  9366. @publisher sysname,
  9367. @subscriber sysname,
  9368. @type tinyint = NULL,
  9369. @login sysname = NULL,
  9370. @password nvarchar(524) = '%',
  9371. @commit_batch_size int = NULL,
  9372. @status_batch_size int = NULL,
  9373. @flush_frequency int = NULL,
  9374. @frequency_type int = NULL,
  9375. @frequency_interval int = NULL,
  9376. @frequency_relative_interval int = NULL,
  9377. @frequency_recurrence_factor int = NULL,
  9378. @frequency_subday int = NULL,
  9379. @frequency_subday_interval int = NULL,
  9380. @active_start_time_of_day int = NULL,
  9381. @active_end_time_of_day int = NULL,
  9382. @active_start_date int = NULL,
  9383. @active_end_date int = NULL,
  9384. @retryattempts int = NULL,
  9385. @retrydelay int = NULL,
  9386. @description nvarchar (255) = NULL,
  9387. @security_mode int = NULL
  9388.  
  9389. AS
  9390.    set nocount on
  9391.    
  9392.    declare @cmd1 nvarchar (255)
  9393.    declare @retcode int
  9394.    declare @platform_nt binary
  9395.  
  9396.    select @platform_nt = 0x1
  9397.  
  9398.    IF (UPPER(@subscriber) = UPPER(@@SERVERNAME) and ( @platform_nt != platform() & @platform_nt ) and @security_mode = 1)
  9399.         BEGIN
  9400.             RAISERROR(21038, 16, -1)
  9401.             RETURN (1)
  9402.         END
  9403.  
  9404.  
  9405.    begin transaction
  9406.    save transaction update_subscriber
  9407.    
  9408.    /* Check if subscriber exists */
  9409.    if not exists (select * from MSsubscriber_info 
  9410.                   where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber))
  9411.        goto FAILED
  9412.  
  9413.    if not exists (select * from MSsubscriber_schedule 
  9414.                   where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0)
  9415.        goto FAILED    
  9416.    
  9417.    if @type is not NULL
  9418.       update MSsubscriber_info set type = @type 
  9419.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  9420.       if @@error <> 0
  9421.          goto FAILED
  9422.    
  9423.    if @security_mode is not NULL
  9424.       update MSsubscriber_info set security_mode = @security_mode 
  9425.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  9426.       if @@error <> 0
  9427.          goto FAILED
  9428.   
  9429.    if @login is not NULL
  9430.       update MSsubscriber_info set login = @login 
  9431.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  9432.       if @@error <> 0
  9433.          goto FAILED
  9434.    
  9435.    if @password <> '%'
  9436.    begin
  9437.         -- Encrypt the password
  9438.         EXEC @retcode = master.dbo.xp_repl_encrypt @password OUTPUT
  9439.         IF @@error <> 0 OR @retcode <> 0
  9440.             goto FAILED
  9441.         update MSsubscriber_info set password = @password 
  9442.             where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  9443.         if @@error <> 0
  9444.             goto FAILED
  9445.    end
  9446.  
  9447.    
  9448.    if @frequency_type is not NULL
  9449.       update MSsubscriber_schedule set frequency_type = @frequency_type 
  9450.         where  UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9451.       if @@error <> 0
  9452.          goto FAILED
  9453.    
  9454.    if @frequency_interval is not NULL
  9455.       update MSsubscriber_schedule set frequency_interval = @frequency_interval 
  9456.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9457.       if @@error <> 0
  9458.          goto FAILED
  9459.    
  9460.    if @frequency_relative_interval is not NULL
  9461.       update MSsubscriber_schedule set frequency_relative_interval = @frequency_relative_interval 
  9462.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9463.        if @@error <> 0
  9464.          goto FAILED
  9465.    
  9466.    if @frequency_recurrence_factor is not NULL
  9467.       update MSsubscriber_schedule set frequency_recurrence_factor = @frequency_recurrence_factor 
  9468.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9469.       if @@error <> 0
  9470.          goto FAILED
  9471.    
  9472.    if @frequency_subday is not NULL
  9473.       update MSsubscriber_schedule set frequency_subday = @frequency_subday 
  9474.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9475.       if @@error <> 0
  9476.          goto FAILED
  9477.    
  9478.    if @frequency_subday_interval is not NULL
  9479.       update MSsubscriber_schedule set frequency_subday_interval = @frequency_subday_interval 
  9480.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9481.       if @@error <> 0
  9482.          goto FAILED
  9483.    
  9484.    if @active_start_time_of_day is not NULL
  9485.       update MSsubscriber_schedule set active_start_time_of_day = @active_start_time_of_day 
  9486.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9487.       if @@error <> 0
  9488.          goto FAILED
  9489.    
  9490.    if @active_end_time_of_day is not NULL
  9491.       update MSsubscriber_schedule set active_end_time_of_day = @active_end_time_of_day 
  9492.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9493.       if @@error <> 0
  9494.          goto FAILED
  9495.    
  9496.    if @active_start_date is not NULL
  9497.       update MSsubscriber_schedule set active_start_date = @active_start_date 
  9498.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9499.       if @@error <> 0
  9500.          goto FAILED
  9501.    
  9502.    if @active_end_date is not NULL
  9503.       update MSsubscriber_schedule set active_end_date = @active_end_date 
  9504.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9505.       if @@error <> 0
  9506.          goto FAILED
  9507.    
  9508.    if @description is not NULL
  9509.       update MSsubscriber_info set description = @description 
  9510.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  9511.       if @@error <> 0
  9512.          goto FAILED
  9513.  
  9514.     if @security_mode is not NULL
  9515.       update MSsubscriber_info set security_mode = @security_mode 
  9516.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  9517.       if @@error <> 0
  9518.          goto FAILED
  9519.  
  9520.    commit transaction
  9521.    return (0)
  9522.    
  9523. FAILED:
  9524.     if @@trancount > 0
  9525.     begin
  9526.         rollback transaction update_subscriber
  9527.         commit tran -- to finish off the tran we started in this proc (though 
  9528.                     -- work was rolled back to savepoint)
  9529.     end
  9530.    return (1)
  9531. GO
  9532.  
  9533. raiserror(15339,-1,-1,'sp_MScheck_Jet_Subscriber')
  9534. GO
  9535. CREATE PROCEDURE sp_MScheck_Jet_Subscriber
  9536. @subscriber                sysname,
  9537. @is_jet                    int OUTPUT,
  9538. @Jet_datasource_path    sysname OUTPUT
  9539. AS
  9540.  
  9541. select @is_jet = 0
  9542. IF EXISTS (select * from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  9543.                 and upper(providername) = 'MICROSOFT.JET.OLEDB.4.0')
  9544. begin
  9545.     select @is_jet = 1
  9546.     select @Jet_datasource_path = datasource from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  9547. end
  9548. return (0)
  9549. GO
  9550.  
  9551. /*
  9552. ** this procedure is to check if merge agent is has expired based on retention
  9553. ** period. Note that if it does, a reinitialization would make it work.
  9554. */
  9555. raiserror(15339,-1,-1,'sp_MScheckretention')
  9556. GO
  9557. CREATE PROCEDURE sp_MScheckretention
  9558. @agent_id                int,
  9559. @schemachangever        int
  9560. AS
  9561. declare     @publisher_id            int
  9562. declare     @publisher_db        sysname
  9563. declare     @publication        sysname
  9564. declare        @expired            int
  9565. declare        @min_valid_day        datetime
  9566. declare        @retention            int
  9567. declare     @success            int
  9568.  
  9569. select @expired  = 0
  9570. select @success = 2
  9571.  
  9572. select @publisher_id=publisher_id, @publisher_db=publisher_db, @publication=publication 
  9573. from MSmerge_agents 
  9574. where id = @agent_id
  9575.  
  9576. select @retention = retention 
  9577. from MSpublications 
  9578. where publisher_id=@publisher_id and publisher_db=@publisher_db and publication=@publication 
  9579.  
  9580. if @retention is not NULL and @retention > 0 and @schemachangever >0
  9581. begin
  9582.     select @min_valid_day = dateadd(day, @retention * (-1), getdate()) 
  9583.     if exists (select * from MSmerge_history where agent_id=@agent_id) 
  9584.             and not exists (select * from MSmerge_history where agent_id=@agent_id and time > @min_valid_day)
  9585.         select @expired = 1
  9586. end
  9587. select @expired 
  9588. GO
  9589.  
  9590. raiserror(15339,-1,-1,'sp_MSupdate_subscriber_schedule')
  9591. GO
  9592. CREATE PROCEDURE sp_MSupdate_subscriber_schedule
  9593. @publisher sysname,
  9594. @subscriber sysname,
  9595. @agent_type tinyint = NULL,
  9596. @frequency_type int = NULL,
  9597. @frequency_interval int = NULL,
  9598. @frequency_relative_interval int = NULL,
  9599. @frequency_recurrence_factor int = NULL,
  9600. @frequency_subday int = NULL,
  9601. @frequency_subday_interval int = NULL,
  9602. @active_start_time_of_day int = NULL,
  9603. @active_end_time_of_day int = NULL,
  9604. @active_start_date int = NULL,
  9605. @active_end_date int = NULL
  9606.  
  9607. AS
  9608.    set nocount on
  9609.    
  9610.    declare @cmd1 nvarchar (255)
  9611.    declare @retcode int
  9612.    
  9613.  
  9614.    begin transaction
  9615.    save transaction update_subscriber_schedule
  9616.    
  9617.    /* Check if subscriber exists */
  9618.    if not exists (select * from MSsubscriber_info 
  9619.             where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber))
  9620.        goto FAILED
  9621.        
  9622.     if not exists (select * from MSsubscriber_schedule 
  9623.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type)
  9624.        goto FAILED
  9625.     
  9626.    
  9627.    if @frequency_type is not NULL
  9628.       update MSsubscriber_schedule set frequency_type = @frequency_type 
  9629.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9630.       if @@error <> 0
  9631.          goto FAILED
  9632.    
  9633.    if @frequency_interval is not NULL
  9634.       update MSsubscriber_schedule set frequency_interval = @frequency_interval 
  9635.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9636.       if @@error <> 0
  9637.          goto FAILED
  9638.    
  9639.    if @frequency_relative_interval is not NULL
  9640.       update MSsubscriber_schedule set frequency_relative_interval = @frequency_relative_interval 
  9641.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9642.       if @@error <> 0
  9643.          goto FAILED
  9644.    
  9645.    if @frequency_recurrence_factor is not NULL
  9646.       update MSsubscriber_schedule set frequency_recurrence_factor = @frequency_recurrence_factor 
  9647.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9648.        if @@error <> 0
  9649.          goto FAILED
  9650.    
  9651.    if @frequency_subday is not NULL
  9652.       update MSsubscriber_schedule set frequency_subday = @frequency_subday 
  9653.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9654.       if @@error <> 0
  9655.          goto FAILED
  9656.    
  9657.    if @frequency_subday_interval is not NULL
  9658.       update MSsubscriber_schedule set frequency_subday_interval = @frequency_subday_interval 
  9659.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9660.       if @@error <> 0
  9661.          goto FAILED
  9662.    
  9663.    if @active_start_time_of_day is not NULL
  9664.       update MSsubscriber_schedule set active_start_time_of_day = @active_start_time_of_day 
  9665.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9666.       if @@error <> 0
  9667.          goto FAILED
  9668.    
  9669.    if @active_end_time_of_day is not NULL
  9670.       update MSsubscriber_schedule set active_end_time_of_day = @active_end_time_of_day 
  9671.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9672.       if @@error <> 0
  9673.          goto FAILED
  9674.    
  9675.    if @active_start_date is not NULL
  9676.       update MSsubscriber_schedule set active_start_date = @active_start_date 
  9677.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9678.       if @@error <> 0
  9679.          goto FAILED
  9680.    
  9681.    if @active_end_date is not NULL
  9682.       update MSsubscriber_schedule set active_end_date = @active_end_date 
  9683.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9684.       if @@error <> 0
  9685.          goto FAILED
  9686.  
  9687.    commit transaction
  9688.    return (0)
  9689.    
  9690. FAILED:
  9691.     if @@trancount > 0
  9692.     begin
  9693.         rollback transaction update_subscriber_schedule
  9694.         commit transaction      -- to finish off the tran we started in this proc (though 
  9695.                                 -- work was rolled back to savepoint)
  9696.     end
  9697.    return (1)
  9698. GO
  9699.  
  9700.  
  9701. raiserror(15339,-1,-1,'sp_MSdrop_subscriber_info')
  9702. GO
  9703. CREATE PROCEDURE sp_MSdrop_subscriber_info
  9704. @publisher sysname,
  9705. @subscriber sysname
  9706.  
  9707. AS
  9708.     set nocount on
  9709.  
  9710.     declare @srvid smallint
  9711.     declare @publisher_id smallint
  9712.     declare @publisher_db sysname
  9713.   
  9714.     if exists (select * from MSsubscriber_info where
  9715.         UPPER(subscriber) = UPPER(@subscriber))
  9716.     begin
  9717.  
  9718.         select @srvid = srvid from master..sysservers where lower(srvname) = lower(@subscriber)
  9719.  
  9720.         -- For SQL server publishers, drop the existing subscriptions.
  9721.         -- This has to be done for 65 upgrade.
  9722.         -- For third party, check for error.
  9723.         if exists (select * from msdb..MSdistpublishers where 
  9724.             lower(name) = lower(@publisher) and
  9725.             thirdparty_flag = 0)
  9726.         begin
  9727.             -- This is needed for 6.5 upgrade.
  9728.             -- Remove subscription entries for this publisher and subscriber pair
  9729.             -- Get dist publisher ID
  9730.             exec dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  9731.             delete MSsubscriptions where subscriber_id = @srvid and 
  9732.                 publisher_id = @publisher_id
  9733.         end
  9734.         else
  9735.         begin
  9736.             if exists (select * from MSsubscriptions where subscriber_id = @srvid)
  9737.             begin
  9738.                 raiserror(20100, 16, -1, @subscriber)
  9739.                 return (1)
  9740.             end
  9741.         end
  9742.  
  9743.         delete MSsubscriber_info where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  9744.         if @@error <> 0
  9745.             return 1
  9746.         delete MSsubscriber_schedule where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  9747.         if @@error <> 0
  9748.             return 1    
  9749.     end
  9750. GO
  9751.  
  9752. -- delete the agent rows that are orphaned for some external reasons, e.g., publishing database dropped,
  9753. -- the agent entry for anonymous TRAN/MERGE subscriptions. 
  9754. -- Can be called directly by user to explicitly cleanup metadata in distribution database
  9755.  
  9756. raiserror(15339,-1,-1,'sp_MScleanup_agent_entry')
  9757. GO
  9758. CREATE PROCEDURE sp_MScleanup_agent_entry
  9759. AS
  9760.     
  9761.     declare @min_valid_day         datetime
  9762.  
  9763.     declare @publisher_id         int
  9764.     declare @subscriber_id         int
  9765.     declare @publication         sysname
  9766.     declare @publisher_db         sysname
  9767.     declare @subscriber_db         sysname
  9768.     declare @retention             int
  9769.     declare @publication_type     int
  9770.     declare @agent_id            int
  9771.         , @num_dropped    int
  9772.         , @retcode int
  9773.  
  9774.     set nocount on
  9775.     select @num_dropped = 0
  9776.  
  9777.     declare PC CURSOR LOCAL FAST_FORWARD for 
  9778.         select distinct publisher_id, publisher_db, publication, retention, publication_type from MSpublications
  9779.             where retention<>0
  9780.     open PC
  9781.     fetch PC into @publisher_id, @publisher_db, @publication, @retention, @publication_type
  9782.     while (@@fetch_status <> -1)
  9783.     begin    
  9784.         if @publication_type = 2  --merge publication
  9785.         begin
  9786.             select @min_valid_day = dateadd(day, @retention * (-2), getdate()) 
  9787.  
  9788.             declare hC CURSOR LOCAL FAST_FORWARD FOR 
  9789.                 select id from MSmerge_agents where creation_date < @min_valid_day
  9790.                     and not exists (select * from MSmerge_history where agent_id = id and time > @min_valid_day)
  9791.                     and publisher_id=@publisher_id
  9792.                     and publisher_db = @publisher_db
  9793.                     and publication = @publication   
  9794.                     -- Only do this for anonymous agents
  9795.                     and subscriber_name is not null         
  9796.             for read only
  9797.             open hC
  9798.             fetch hC into @agent_id
  9799.             while (@@fetch_status <> -1)
  9800.             begin
  9801.                 exec @retcode = dbo.sp_MSdrop_merge_agentid @agent_id
  9802.                 if @retcode <> 0 or @@error <> 0
  9803.                     return (1)
  9804.                 select @num_dropped = @num_dropped + 1
  9805.                 fetch hC into @agent_id
  9806.             end
  9807.             close hC
  9808.             deallocate hC
  9809.         end
  9810.            else if @publication_type in (0,1) --Tran level publication
  9811.               begin  
  9812.                 select @min_valid_day = dateadd(hour, @retention * (-1), getdate())    
  9813.                 -- Only do this for anonymous agents
  9814.                 declare hC CURSOR LOCAL FAST_FORWARD FOR 
  9815.                     select id from MSdistribution_agents where creation_date < @min_valid_day
  9816.                         and not exists (select * from MSdistribution_history where agent_id = id and time > @min_valid_day)
  9817.                         and publisher_id=@publisher_id
  9818.                         and publisher_db = @publisher_db
  9819.                         and publication = @publication            
  9820.                         -- Only do this for anonymous agents
  9821.                         and subscriber_name is not null                             
  9822.                 for read only
  9823.                 open hC
  9824.                 fetch hC into @agent_id
  9825.                 while (@@fetch_status <> -1)
  9826.                 begin
  9827.                     exec @retcode = dbo.sp_MSdrop_distribution_agentid @agent_id
  9828.                     if @retcode <> 0 or @@error <> 0
  9829.                         return (1)
  9830.                     select @num_dropped = @num_dropped + 1
  9831.                     fetch hC into @agent_id
  9832.                 end
  9833.             close hC
  9834.             deallocate hC
  9835.             end
  9836.           fetch PC into @publisher_id, @publisher_db, @publication, @retention, @publication_type
  9837.     end
  9838.     close PC
  9839.     deallocate PC
  9840.     if @num_dropped > 0
  9841.         RAISERROR(20597, 10, -1, @num_dropped) 
  9842.        return (0)
  9843. FAILURE:
  9844.     close PC
  9845.     deallocate PC
  9846.        return (1)        
  9847. GO
  9848.  
  9849. raiserror(15339,-1,-1,'sp_MShelp_subscription_status')
  9850. GO
  9851. CREATE PROCEDURE sp_MShelp_subscription_status(
  9852. @publisher          sysname,
  9853. @publisher_db       sysname,
  9854. @publication        sysname,
  9855. @subscriber         sysname,
  9856. @subscriber_db      sysname,
  9857. @retention          int,
  9858. @out_of_date        int OUTPUT,
  9859. @independent_agent  bit = 0
  9860. )AS
  9861.  
  9862. declare @subscriber_id          int
  9863. declare @publisher_id           int
  9864. declare @publication_id         int
  9865. declare @retcode                int
  9866. declare @agent_id               int
  9867. declare @min_valid_day          datetime
  9868. declare @subscription_time      datetime
  9869. declare @last_history            datetime
  9870. declare @last_status            int
  9871.  
  9872. select @out_of_date = 0 -- Default value set to in-sync
  9873. select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  9874. select @subscriber_id = srvid from master..sysservers where UPPER(srvname)=UPPER(@subscriber)
  9875.  
  9876. select  @publication_id = publication_id
  9877.         from MSpublications where
  9878.         publisher_id = @publisher_id and
  9879.         publisher_db = @publisher_db and
  9880.         publication = @publication
  9881.  
  9882. select @subscription_time = subscription_time
  9883.         from MSsubscriptions where
  9884.             publisher_id = @publisher_id and
  9885.             publisher_db = @publisher_db and
  9886.             publication_id = @publication_id and
  9887.             subscriber_id = @subscriber_id and
  9888.             subscriber_db = @subscriber_db
  9889.             
  9890. select @min_valid_day = dateadd(hour, -@retention, getdate())
  9891.         
  9892. BEGIN TRAN
  9893.     select @agent_id = id from MSdistribution_agents 
  9894.         where   publisher_id = @publisher_id and 
  9895.                 publisher_db = @publisher_db and 
  9896.                 ((publication = @publication and @independent_agent = 1 ) 
  9897.                     or (LOWER(publication) = 'all' and @independent_agent = 0)) and
  9898.                 subscriber_id = @subscriber_id and  
  9899.                 subscriber_db = @subscriber_db
  9900.  
  9901.     if @agent_id is NOT NULL
  9902.         begin
  9903.             select Top 1 @last_status = runstatus, @last_history = time 
  9904.                 from MSdistribution_history where agent_id = @agent_id
  9905.                     order by timestamp DESC
  9906.                     
  9907.             -- if failure then get the last success; if any; else use the existing value                    
  9908.             
  9909.             if @last_status = 6 and EXISTS (select * from MSdistribution_history where agent_id = @agent_id and runstatus = 2) 
  9910.                 select Top 1 @last_history = time 
  9911.                     from MSdistribution_history where agent_id = @agent_id and runstatus = 2
  9912.                         order by timestamp DESC    
  9913.             
  9914.             if EXISTS (select * from MSdistribution_history where agent_id = @agent_id) and (@last_history < @min_valid_day)
  9915.                 and (@retention <> 0)
  9916.                 select @out_of_date = 1
  9917.             else 
  9918.                 if (not EXISTS (select * from MSdistribution_history where agent_id = @agent_id)) and
  9919.                         (@subscription_time < @min_valid_day) and (@retention <> 0)
  9920.                 select @out_of_date = 1
  9921.         end
  9922.         
  9923. COMMIT TRAN
  9924. return (0)
  9925.  
  9926. FAILURE:
  9927.     if @@TRANCOUNT = 1
  9928.         ROLLBACK TRAN
  9929.     else
  9930.         COMMIT TRAN
  9931.     return (1)
  9932. GO
  9933.  
  9934.  
  9935.  
  9936. raiserror(15339,-1,-1,'sp_MShelp_subscriber_info')
  9937. GO
  9938. CREATE PROCEDURE sp_MShelp_subscriber_info
  9939. @publisher sysname = '%',
  9940. @subscriber sysname = '%',
  9941. @found int = NULL    OUTPUT,
  9942. @show_password bit = 1
  9943.  
  9944. AS
  9945.    set nocount on
  9946.    
  9947.    DECLARE @no_rows bit
  9948.  
  9949.     -- push agents (dist or merge) may call this.
  9950.     -- raise an message indicating that users may forget to specify -SubscriptionType
  9951.     if is_member(N'db_owner') <> 1
  9952.     begin
  9953.         raiserror (20604, 16, -1)
  9954.         return 1
  9955.     end
  9956.  
  9957.     /*
  9958.     ** Initializations.
  9959.     */
  9960.     IF @found is NULL
  9961.     BEGIN
  9962.         SELECT @no_rows=0
  9963.     END
  9964.     ELSE
  9965.     BEGIN
  9966.         SELECT @no_rows=1
  9967.     END
  9968.  
  9969.    if exists (select * from MSsubscriber_info 
  9970.                where (@publisher = '%' or UPPER(publisher) = UPPER(@publisher)) 
  9971.                  and (@subscriber = '%' or UPPER(subscriber) = UPPER(@subscriber)))
  9972.    begin
  9973.         select @found = 1
  9974.         if @no_rows <>0 return(0)
  9975.    end
  9976.    else
  9977.    begin
  9978.         select @found = 0
  9979.         if @no_rows <>0 return(0)
  9980.    end
  9981.  
  9982.    if exists (select * from MSsubscriber_schedule 
  9983.                where (@publisher = N'%' or UPPER(publisher) = UPPER(@publisher))
  9984.                  and (@subscriber = N'%' or UPPER(subscriber) = UPPER(@subscriber)))
  9985.     begin
  9986.     
  9987.      select Sinfo.publisher,
  9988.             Sinfo.subscriber,
  9989.             Sinfo.type,
  9990.             Sinfo.login,
  9991.             case when @show_password = 1 then Sinfo.password
  9992.             else convert(sysname, NULL) end,
  9993.             100,  -- commit_batch_size, no longer supported
  9994.             100,  -- status_batch_size, no longer supported
  9995.             1,    -- flush_frequency, no longer supported
  9996.             sch1.frequency_type, 
  9997.             sch1.frequency_interval,
  9998.             sch1.frequency_relative_interval,
  9999.             sch1.frequency_recurrence_factor,
  10000.             sch1.frequency_subday,
  10001.             sch1.frequency_subday_interval,
  10002.             sch1.active_start_time_of_day,
  10003.             sch1.active_end_time_of_day,
  10004.             sch1.active_start_date,
  10005.             sch1.active_end_date,
  10006.             4, -- retryattempt, no longer exist
  10007.             4,  -- retrydelay, no longer exist
  10008.             Sinfo.description,
  10009.             Sinfo.security_mode,
  10010.             sch2.frequency_type, 
  10011.             sch2.frequency_interval,
  10012.             sch2.frequency_relative_interval,
  10013.             sch2.frequency_recurrence_factor,
  10014.             sch2.frequency_subday,
  10015.             sch2.frequency_subday_interval,
  10016.             sch2.active_start_time_of_day,
  10017.             sch2.active_end_time_of_day,
  10018.             sch2.active_start_date,
  10019.             sch2.active_end_date
  10020.             
  10021.     from (MSsubscriber_info as Sinfo LEFT OUTER JOIN MSsubscriber_schedule as sch1 
  10022.         on UPPER(Sinfo.publisher)=UPPER(sch1.publisher) AND UPPER(Sinfo.subscriber)=UPPER(sch1.subscriber) and sch1.agent_type=0)
  10023.         LEFT OUTER JOIN MSsubscriber_schedule as sch2
  10024.             on UPPER(Sinfo.publisher)=UPPER(sch2.publisher) AND UPPER(Sinfo.subscriber)=UPPER(sch2.subscriber) 
  10025.                     and sch2.agent_type=1
  10026.     where (@publisher = N'%' or UPPER(Sinfo.publisher) = UPPER(@publisher)) and 
  10027.           (@subscriber = N'%' or UPPER(Sinfo.subscriber) = UPPER(@subscriber))                 
  10028.     
  10029.     end
  10030. GO
  10031.  
  10032. raiserror(15339,-1,-1,'sp_MSdistribution_counters')
  10033. go
  10034. CREATE PROCEDURE sp_MSdistribution_counters
  10035. @publisher sysname      /* publication server name */
  10036. AS
  10037.  
  10038.     set nocount on
  10039.  
  10040.     declare @publisher_id smallint
  10041.     declare @subscriber_id smallint
  10042.     declare @active_status tinyint
  10043.     declare @snapshot_bit int
  10044.     declare @undelivered_commands int
  10045.     declare @delivered_commands int
  10046.     declare @delivery_rate float
  10047.     declare @delivery_latency int
  10048.     declare @xact_seqno varbinary(16)
  10049.     declare @agent_id int
  10050.     
  10051.     select @active_status = 2
  10052.     select @snapshot_bit = 0x80000000
  10053.  
  10054.  
  10055.     -- Make sure publisher is defined on distributor
  10056.     --
  10057.     select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  10058.     if @publisher_id is null
  10059.        return (1)
  10060.  
  10061.     create table #dist_trans (subscriber_id smallint NOT NULL, undelivered_commands int NOT NULL, 
  10062.         delivered_commands int NOT NULL, delivery_rate float NOT NULL, 
  10063.         delivery_latency int NOT NULL)
  10064.  
  10065.     declare hc CURSOR LOCAL FAST_FORWARD FOR select distinct agent_id
  10066.         from MSsubscriptions
  10067.         where
  10068.         publisher_id = @publisher_id and
  10069.         subscriber_id >= 0 and
  10070.         status = 2
  10071.         for read only
  10072.  
  10073.     open hc
  10074.     fetch hc into  @agent_id
  10075.     while (@@fetch_status <> -1)
  10076.     begin
  10077.         -- Get the lastest numbers from distribution_history
  10078.         select  @xact_seqno = NULL
  10079.  
  10080.         -- Get latest seqno, rate and latency
  10081.         set rowcount 1
  10082.         select  @xact_seqno = xact_seqno,
  10083. --              @delivered_commands = delivered_commands,
  10084.                 @delivery_rate = current_delivery_rate,
  10085.                 @delivery_latency = current_delivery_latency
  10086.             -- from MSdistribution_history  (READPAST)
  10087.             from MSdistribution_history 
  10088.             where
  10089.             agent_id = @agent_id and
  10090.             xact_seqno <> 0x0
  10091.             order by timestamp DESC
  10092.         set rowcount 0
  10093.  
  10094.         if @xact_seqno IS NULL
  10095.             select  @xact_seqno = 0x00,
  10096.                     @delivery_rate = 0,
  10097.                     @delivery_latency = 0
  10098.  
  10099.  
  10100.         set rowcount 1
  10101.         select @subscriber_id = subscriber_id FROM MSsubscriptions
  10102.             where agent_id = @agent_id
  10103.         set rowcount 0
  10104.         
  10105.         -- Get the delivered trans number
  10106.         select @delivered_commands = 0
  10107.         select @delivered_commands = isnull(count(*), 0)
  10108.             from
  10109.             -- MSrepl_commands rc (READPAST), MSsubscriptions s
  10110.             MSrepl_commands rc, MSsubscriptions s
  10111.             where
  10112.             /*
  10113.             ** Query from sp_MSget_repl_commands
  10114.             */
  10115.             s.agent_id = @agent_id and
  10116.             s.status = @active_status and
  10117.             rc.publisher_database_id = s.publisher_database_id and
  10118. --          rc.publisher_id = s.publisher_id and
  10119. --          rc.publisher_db = s.publisher_db and
  10120.             rc.xact_seqno <= @xact_seqno and
  10121.             rc.article_id = s.article_id and
  10122.             rc.partial_command = 0
  10123.             and
  10124.             ((rc.xact_seqno >= s.subscription_seqno and (rc.type & @snapshot_bit) <> @snapshot_bit) or
  10125.             rc.xact_seqno = s.subscription_seqno)
  10126.  
  10127.         -- Get the undelivered trans number
  10128.         select @undelivered_commands = 0
  10129.         select @undelivered_commands = isnull(count(*), 0)
  10130.             from
  10131.             -- MSrepl_commands rc (READPAST), MSsubscriptions s
  10132.             MSrepl_commands rc , MSsubscriptions s
  10133.             where
  10134.             /*
  10135.             ** Query from sp_MSget_repl_commands
  10136.             */
  10137.             s.agent_id = @agent_id and
  10138.             s.status = @active_status and
  10139.             rc.publisher_database_id = s.publisher_database_id and
  10140.             rc.xact_seqno > @xact_seqno and
  10141.             rc.article_id = s.article_id and
  10142.             rc.partial_command = 0
  10143.             and
  10144.             ((rc.xact_seqno >= s.subscription_seqno and (rc.type & @snapshot_bit) <> @snapshot_bit) or
  10145.             rc.xact_seqno = s.subscription_seqno)
  10146.  
  10147.         insert into #dist_trans values (@subscriber_id, @undelivered_commands,
  10148.             @delivered_commands, @delivery_rate, @delivery_latency)
  10149.         
  10150.         fetch hc into  @agent_id
  10151.     end
  10152.  
  10153.     close hc
  10154.     deallocate hc
  10155.  
  10156.     select 'subscriber' = srvname, 
  10157.             'delivered commands' = sum(delivered_commands),
  10158.             'undelivered_commands' = sum(undelivered_commands),
  10159.             'delivery_rate' = sum(delivery_rate),
  10160.             'delivery_latency' = (select isnull(avg(delivery_latency), 0) from #dist_trans, master.dbo.sysservers where
  10161.                 srvname = s1.srvname and delivery_latency > 0)
  10162.         from #dist_trans, master.dbo.sysservers s1
  10163.         where subscriber_id = srvid
  10164.         group by srvname
  10165.  
  10166.     drop table #dist_trans
  10167.         
  10168. GO
  10169.  
  10170. raiserror(15339,-1,-1,'sp_MSremove_published_jobs')
  10171. go
  10172. CREATE PROCEDURE sp_MSremove_published_jobs
  10173. @server sysname,
  10174. @database sysname
  10175. AS
  10176.     -- 6.5 publisher and 7.0 publisher will call this
  10177.     -- publisher_database_id will be drop in sp_MSdrop_publication.
  10178.     return(0)
  10179. go
  10180.  
  10181. raiserror(15339,-1,-1,'sp_MSset_snapshot_xact_seqno')
  10182. go
  10183.  
  10184. CREATE PROCEDURE sp_MSset_snapshot_xact_seqno
  10185. @publisher_id int,
  10186. @publisher_db sysname,
  10187. @article_id int, 
  10188. @xact_seqno varbinary(16),
  10189. @reset bit = 0,         /* @reset = 1 is used for Scheduled Snapshot publications by snapshot */
  10190. @publication sysname = NULL,
  10191. @publisher_seqno varbinary(16) = 0x00,
  10192. @ss_cplt_seqno varbinary(16) = NULL
  10193. /* 
  10194. ** Required for 6x publishers!
  10195. */
  10196. AS
  10197.  
  10198.     DECLARE @virtual smallint     /* const: virtual subscriber id */
  10199.     DECLARE @virtual_anonymous smallint /* const: virtual anonymous subscriber id */
  10200.     DECLARE @old_xact_seqno varbinary(16)
  10201.     DECLARE @old_publisher_seqno varbinary(16)
  10202.     DECLARE @subscribed tinyint
  10203.     DECLARE @automatic tinyint
  10204.     DECLARE @old_snapshot_seqno_flag bit
  10205.     DECLARE @publication_id int
  10206.     DECLARE @initiated tinyint
  10207.  
  10208.     SELECT @virtual = -1
  10209.     SELECT @virtual_anonymous = -2
  10210.     SELECT @subscribed = 1
  10211.     SELECT @automatic = 1
  10212.     SELECT @initiated = 3
  10213.     
  10214.     if @ss_cplt_seqno is null 
  10215.     begin
  10216.         select @ss_cplt_seqno = @xact_seqno;
  10217.     end
  10218.  
  10219.     -- 6.5 only!!! @publication is not null only if the publisher is 6.5 sever!
  10220.     -- Set the publication_id and sync_type in MSsubscriptions.
  10221.     -- It will be used in sp_MSupdate_subscriptions 
  10222.     IF @publication IS NOT NULL
  10223.     BEGIN
  10224.         -- Get the publication id
  10225.         SELECT @publication_id = publication_id FROM MSpublications
  10226.             WHERE   publisher_id = @publisher_id AND
  10227.                     publisher_db = @publisher_db AND    
  10228.                     publication  = @publication
  10229.  
  10230.         -- Set the pubid and the sync_type
  10231.         -- Avoid update rows with no change to reduce update locks.
  10232.         
  10233.         UPDATE MSsubscriptions SET publication_id = @publication_id
  10234.             WHERE   publisher_id = @publisher_id AND
  10235.                     publisher_db = @publisher_db AND    
  10236.                     article_id  = @article_id and
  10237.                     status = @subscribed and
  10238.                     publication_id <> @publication_id
  10239.         
  10240.         -- Have to do this to avoid no sync subs from 6.5 publisher being
  10241.         -- updated.
  10242.         UPDATE MSsubscriptions SET sync_type = @automatic
  10243.             WHERE   publisher_id = @publisher_id AND
  10244.                     publisher_db = @publisher_db AND    
  10245.                     article_id  = @article_id and
  10246.                     status = @subscribed and
  10247.                     sync_type <> @automatic
  10248.     END
  10249.  
  10250.     begin tran
  10251.     save TRANSACTION MSset_snapshot_xact_seqno
  10252.  
  10253.     /* 
  10254.     ** Set snapshot_xact_seqno for all new subscriptions,
  10255.     ** plus the virtual subscription or all subscriptions if @reset = 1
  10256.     ** Note virtual anonymous subscription will not be set
  10257.     ** (2 virtual subscriptions of anonymous publication will be activated
  10258.     ** immediately without snapshot
  10259.     ** 
  10260.     ** @reset = 1 is used for Scheduled Snapshot publications by snapshot
  10261.     */
  10262.     UPDATE MSsubscriptions SET subscription_seqno = @xact_seqno,
  10263.         publisher_seqno = @publisher_seqno,
  10264.         snapshot_seqno_flag = 1,
  10265.         subscription_time = getdate(),
  10266.         ss_cplt_seqno = @ss_cplt_seqno
  10267.       WHERE 
  10268.          MSsubscriptions.publisher_id = @publisher_id and
  10269.          MSsubscriptions.publisher_db = @publisher_db and
  10270.          MSsubscriptions.article_id = @article_id and 
  10271.          /* virtual subscriptions are automatic sync type */
  10272.          MSsubscriptions.sync_type = @automatic and 
  10273.          (MSsubscriptions.status in(@subscribed,@initiated) or 
  10274.          MSsubscriptions.subscriber_id = @virtual or
  10275.          -- Set for virtual anonymous account if snapshot_seqno_flag
  10276.          -- is 0.
  10277.          -- The virtual anonymous account is activated immediately at subscription
  10278.          -- time for no init option for anonymous agent.
  10279.          (MSsubscriptions.subscriber_id = @virtual_anonymous and 
  10280.          (MSsubscriptions.snapshot_seqno_flag = 0 or 
  10281.          MSsubscriptions.status in(@subscribed,@initiated))) or
  10282.          @reset = 1) 
  10283.  
  10284.     IF @@ERROR <> 0
  10285.     BEGIN
  10286.         if @@trancount > 0
  10287.         begin
  10288.             ROLLBACK TRANSACTION MSset_snapshot_xact_seqno
  10289.             commit tran
  10290.         end
  10291.         RETURN (1)
  10292.     END
  10293.  
  10294.     COMMIT TRANSACTION
  10295. GO
  10296.  
  10297.  
  10298. raiserror(15339,-1,-1,'sp_MSdrop_article')
  10299. go
  10300. CREATE PROCEDURE sp_MSdrop_article
  10301. @publisher sysname,
  10302. @publisher_db sysname,
  10303. @publication sysname,
  10304. @article sysname
  10305.  
  10306. as
  10307.  
  10308.     set nocount on
  10309.  
  10310.     declare @publisher_id smallint
  10311.     declare @publication_id int
  10312.     declare @article_id int
  10313.     declare @retcode int
  10314.     declare @thirdparty_flag bit
  10315.     declare @immediate_sync bit
  10316.  
  10317.     -- Check if publisher is a defined as a distribution publisher in the current database
  10318.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  10319.     if @retcode <> 0
  10320.     begin
  10321.         return(1)
  10322.     end
  10323.  
  10324.     -- Make sure publication exists
  10325.     select @publication_id = publication_id, @thirdparty_flag = thirdparty_flag,
  10326.         @immediate_sync = immediate_sync
  10327.         from MSpublications where 
  10328.         publication = @publication and
  10329.         publisher_id = @publisher_id and 
  10330.         publisher_db = @publisher_db
  10331.     if @publication_id is NULL
  10332.     begin
  10333.         raiserror(20026, 16, -1, @publication)
  10334.         return (1)
  10335.     end
  10336.  
  10337.     -- Make sure article exists
  10338.     declare @source_object sysname
  10339.     select @article_id = article_id, @source_object = source_object
  10340.         from MSarticles where 
  10341.         publication_id = @publication_id and
  10342.         publisher_id = @publisher_id and 
  10343.         publisher_db = @publisher_db and 
  10344.         article = @article
  10345.     if @article_id is NULL
  10346.     begin
  10347.         if @thirdparty_flag = 1
  10348.         begin
  10349.             raiserror(20027, 16, -1, @article)
  10350.             return (1)
  10351.         end
  10352.         else
  10353.             return (0)
  10354.     end
  10355.  
  10356.     -- Check to make sure that there are no subscriptions on the article
  10357.     if exists (select * from MSsubscriptions where 
  10358.         publisher_id = @publisher_id and
  10359.         publisher_db = @publisher_db and
  10360.         publication_id = @publication_id and
  10361.         article_id = @article_id and
  10362.         subscriber_id >= 0)             -- ignore virtual subscriptions
  10363.     begin
  10364.         raiserror(14046, 16, -1)
  10365.         return(1)
  10366.     end
  10367.  
  10368.     begin tran
  10369.     save tran MSdrop_article
  10370.  
  10371.     -- For third party publications drop immediate sync and anonymous virtual subscriptions
  10372.     -- SQL Server publications will do this via RPC calls to sp_MSadd_subscription
  10373.     if @thirdparty_flag = 1 and @immediate_sync = 1
  10374.     begin
  10375.         begin
  10376.             exec @retcode = dbo.sp_MSdrop_subscription
  10377.                 @publisher = @publisher,
  10378.                 @publisher_db = @publisher_db,
  10379.                 @publication = @publication,
  10380.                 @article_id = @article_id,
  10381.                 @subscriber = NULL                  -- virtual subscription
  10382.             if @retcode <> 0 or @@error <> 0
  10383.             begin
  10384.                 if @@trancount > 0
  10385.                 begin
  10386.                     rollback tran MSdrop_article
  10387.                     commit tran
  10388.                 end
  10389.                 return (1)
  10390.             end
  10391.         end
  10392.     end
  10393.  
  10394.     delete from MSarticles where
  10395.         publisher_id = @publisher_id and
  10396.         publisher_db = @publisher_db and
  10397.         publication_id = @publication_id and
  10398.         article_id = @article_id
  10399.     if @@error <> 0
  10400.     begin
  10401.         if @@trancount > 0
  10402.         begin
  10403.             rollback tran MSdrop_article
  10404.             commit tran
  10405.         end
  10406.         return (1)
  10407.     end
  10408.  
  10409.     if not exists (select * from MSarticles  where 
  10410.         publisher_id = @publisher_id and
  10411.         publisher_db = @publisher_db and
  10412.         source_object = @source_object)
  10413.     begin
  10414.         delete MSrepl_identity_range where 
  10415.             publisher = @publisher and
  10416.             publisher_db = @publisher_db and
  10417.             tablename = @source_object
  10418.         if @@ERROR <> 0 begin
  10419.             if @@trancount > 0
  10420.                 ROLLBACK TRAN
  10421.             RETURN (1)
  10422.         end
  10423.     end
  10424.  
  10425.     commit tran
  10426. go
  10427.  
  10428. raiserror(15339,-1,-1,'sp_MSdrop_snapshot_agent')
  10429. GO
  10430. CREATE PROCEDURE sp_MSdrop_snapshot_agent (
  10431.     @publisher sysname,
  10432.     @publisher_db sysname,
  10433.     @publication sysname
  10434. ) AS
  10435.  
  10436.  
  10437.     SET NOCOUNT ON
  10438.  
  10439.     /*
  10440.     ** Declarations.
  10441.     */
  10442.     DECLARE @retcode    int
  10443.     DECLARE @job_id     binary(16)
  10444.     DECLARE @local_job  bit
  10445.     DECLARE @publisher_id smallint
  10446.     DECLARE @name       nvarchar(100)
  10447.     DECLARE @agent_id   int
  10448.  
  10449.     /*
  10450.     ** Initializations
  10451.     */
  10452.     select @publisher_id = srvid from master..sysservers where
  10453.         UPPER(srvname) = UPPER(@publisher)
  10454.  
  10455.  
  10456.  
  10457.     SELECT @job_id = job_id, @local_job = local_job, @name = name, @agent_id = id  FROM MSsnapshot_agents WHERE
  10458.         publisher_id = @publisher_id AND
  10459.         publisher_db = @publisher_db AND
  10460.         publication = @publication
  10461.  
  10462.     -- Delete Perfmon instance
  10463.     dbcc deleteinstance ("SQL Replication Snapshot", @name)
  10464.  
  10465.     -- Return if not exists
  10466.     IF @local_job IS NULL
  10467.         RETURN(0)
  10468.  
  10469.     BEGIN TRAN
  10470.  
  10471.     IF @local_job = 1
  10472.     BEGIN
  10473.         -- Don't drop the job for third party publications.
  10474.         if exists (select * from msdb..MSdistpublishers where 
  10475.             UPPER(name) = UPPER(@publisher) and
  10476.             thirdparty_flag = 0)
  10477.         begin                            
  10478.             IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  10479.             BEGIN
  10480.                 EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  10481.                 IF @@ERROR <> 0 or @retcode <> 0
  10482.                     GOTO UNDO
  10483.             END
  10484.         end
  10485.     END
  10486.  
  10487.     DELETE MSsnapshot_agents WHERE id = @agent_id
  10488.     IF @@ERROR <> 0 
  10489.         GOTO UNDO
  10490.  
  10491.     -- Remove history
  10492.     DELETE MSsnapshot_history WHERE agent_id = @agent_id
  10493.     IF @@ERROR <> 0 
  10494.         GOTO UNDO
  10495.  
  10496.     IF @@ERROR <> 0 
  10497.         GOTO UNDO
  10498.  
  10499.     -- Update global replication status table
  10500.     EXEC dbo.sp_MSupdate_replication_status
  10501.         @publisher,
  10502.         @publisher_db,
  10503.         @publication,
  10504.         @agent_type = 1,
  10505.         @agent_name = @name,
  10506.         @status = -1    -- delete status
  10507.  
  10508.     COMMIT TRAN
  10509.  
  10510.     RETURN(0)
  10511.  
  10512. UNDO:
  10513.     if @@TRANCOUNT = 1
  10514.         ROLLBACK TRAN
  10515.     else
  10516.         COMMIT TRAN
  10517.     return(1)
  10518. GO
  10519.  
  10520.  
  10521. raiserror(15339,-1,-1,'sp_MSdrop_logreader_agent')
  10522. GO
  10523. CREATE PROCEDURE sp_MSdrop_logreader_agent (
  10524.     @publisher sysname,
  10525.     @publisher_db sysname,
  10526.     @publication sysname  --Only used by 3rd party publisher
  10527. ) AS
  10528.  
  10529.  
  10530.     SET NOCOUNT ON
  10531.  
  10532.     /*
  10533.     ** Declarations.
  10534.     */
  10535.     DECLARE @retcode    int
  10536.     DECLARE @job_id     binary(16)
  10537.     DECLARE @local_job  bit
  10538.     DECLARE @publisher_id smallint
  10539.     DECLARE @name       nvarchar(100)
  10540.     DECLARE @agent_id   int
  10541.  
  10542.     /*
  10543.     ** Initializations
  10544.     */
  10545.     select @publisher_id = srvid from master..sysservers where
  10546.         UPPER(srvname) = UPPER(@publisher)
  10547.  
  10548.  
  10549.     SELECT @job_id = job_id, @local_job = local_job, @name = name, @agent_id = id FROM MSlogreader_agents WHERE
  10550.         publisher_id = @publisher_id AND
  10551.         publisher_db = @publisher_db AND
  10552.         publication = @publication
  10553.  
  10554.     -- Delete Perfmon instance
  10555.     dbcc deleteinstance ("SQL Replication Logreader", @name)
  10556.  
  10557.     -- Return if not exists
  10558.     IF @local_job IS NULL
  10559.         RETURN(0)
  10560.  
  10561.     BEGIN TRAN
  10562.  
  10563.     IF @local_job = 1
  10564.     BEGIN
  10565.         -- Don't drop the job for third party publications.
  10566.         if exists (select * from msdb..MSdistpublishers where 
  10567.             UPPER(name) = UPPER(@publisher) and
  10568.             thirdparty_flag = 0)
  10569.         begin                            
  10570.             IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  10571.             BEGIN
  10572.                 EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  10573.                 IF @@ERROR <> 0 or @retcode <> 0
  10574.                     GOTO UNDO
  10575.             END
  10576.         end
  10577.     END
  10578.  
  10579.     DELETE MSlogreader_agents WHERE id = @agent_id
  10580.     IF @@ERROR <> 0 
  10581.         GOTO UNDO
  10582.  
  10583.     -- Remove history
  10584.     DELETE MSlogreader_history WHERE
  10585.         agent_id = @agent_id
  10586.  
  10587.     IF @@ERROR <> 0 
  10588.         GOTO UNDO
  10589.  
  10590.     -- Update global replication status table
  10591.     EXEC dbo.sp_MSupdate_replication_status
  10592.         @publisher,
  10593.         @publisher_db,
  10594.         @publication,
  10595.         @agent_type = 2,
  10596.         @agent_name = @name,
  10597.         @status = -1    -- delete status
  10598.  
  10599.     COMMIT TRAN
  10600.  
  10601.     RETURN(0)
  10602.  
  10603. UNDO:
  10604.     if @@TRANCOUNT = 1
  10605.         ROLLBACK TRAN
  10606.     else
  10607.         COMMIT TRAN
  10608.     return(1)
  10609. GO
  10610.  
  10611. raiserror(15339,-1,-1,'sp_MSdrop_publication')
  10612. go
  10613. CREATE PROCEDURE sp_MSdrop_publication
  10614. @publisher sysname,
  10615. @publisher_db sysname,
  10616. @publication sysname
  10617. as
  10618.  
  10619.     set nocount on
  10620.  
  10621.     declare @publisher_id smallint
  10622.     declare @publication_id int
  10623.     declare @retcode int
  10624.     declare @article sysname
  10625.     declare @thirdparty_flag bit
  10626.     DECLARE @working_dir nvarchar(255)
  10627.     DECLARE @pub_dir nvarchar(255)
  10628.  
  10629.  
  10630.     -- Check if publisher is a defined as a distribution publisher in the current database
  10631.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  10632.     if @retcode <> 0
  10633.     begin
  10634.         return(1)
  10635.     end
  10636.  
  10637.     -- Make sure publication exists
  10638.     select @publication_id = publication_id, @thirdparty_flag = thirdparty_flag 
  10639.         from MSpublications where publication = @publication and
  10640.         publisher_id = @publisher_id and publisher_db = @publisher_db
  10641.     if @publication_id is NULL
  10642.     begin
  10643.         -- We don't know whether or not it is a third party or not so we can not 
  10644.         -- return error.
  10645.         -- raiserror(20026, 16, -1, @publication)
  10646.         -- return (1)
  10647.         return (0)
  10648.     end
  10649.  
  10650.     -- Make sure that there are no subscriptions on the publication.
  10651.     if exists (select * from MSsubscriptions s, MSpublications p where 
  10652.         p.publisher_id = @publisher_id and
  10653.         p.publisher_db = @publisher_db and
  10654.         p.publication = @publication and
  10655.         s.publisher_id = @publisher_id and
  10656.         s.publisher_db = @publisher_db and
  10657.         s.publication_id = p.publication_id and
  10658.         s.subscriber_id >= 0)               -- ignore virtual subscriptions
  10659.     begin
  10660.         raiserror(14005, 16, -1)
  10661.         return(1)
  10662.     end
  10663.  
  10664.     SELECT @working_dir = working_directory FROM msdb..MSdistpublishers
  10665.         where UPPER(name) = UPPER(@publisher)
  10666.  
  10667.     IF @working_dir IS NOT NULL
  10668.     BEGIN
  10669.  
  10670.         -- Remove the pub dir under UNC and FTP if it exists
  10671.         -- Note: sp_MSreplremoveuncdir will convert unc path to local path.
  10672.         -- This is required. Otherwise we will see 'Access denied' error.
  10673.         SELECT @pub_dir = @working_dir + '\unc\' + 
  10674.                     fn_replcomposepublicationsnapshotfolder(@publisher,@publisher_db,@publication) collate database_default
  10675.         exec @retcode = sp_MSreplremoveuncdir @pub_dir
  10676.         if @retcode <> 0 or @@error <> 0
  10677.             return(1)
  10678.  
  10679.  
  10680.         SELECT @pub_dir = @working_dir + '\ftp\' + 
  10681.                     fn_replcomposepublicationsnapshotfolder(@publisher,@publisher_db,@publication) collate database_default
  10682.         exec @retcode = sp_MSreplremoveuncdir @pub_dir
  10683.         if @retcode <> 0 or @@error <> 0
  10684.             return(1)
  10685.     END
  10686.  
  10687.     begin tran
  10688.     save tran MSdrop_publication
  10689.  
  10690.     -- Delete all articles if a third party publication
  10691.     if @thirdparty_flag = 1 
  10692.     begin
  10693.         -- Delete all articles in the publication
  10694.         declare hCarticles CURSOR LOCAL FAST_FORWARD FOR select article from MSarticles where 
  10695.             publisher_id = @publisher_id and
  10696.             publisher_db = @publisher_db and
  10697.             publication_id = 
  10698.                 (select publication_id from MSpublications where 
  10699.                     publisher_id = @publisher_id and
  10700.                     publisher_db = @publisher_db and
  10701.                     publication = @publication)
  10702.         open hCarticles
  10703.         fetch hCarticles into @article
  10704.         while (@@fetch_status <> -1)
  10705.         begin
  10706.             exec @retcode = dbo.sp_MSdrop_article @publisher, @publisher_db, @publication, @article
  10707.             if @retcode != 0 or @@error != 0
  10708.             begin
  10709.                 close hCarticles
  10710.                 deallocate hCarticles
  10711.                 if @@trancount > 0
  10712.                 begin
  10713.                     rollback tran MSdrop_publication
  10714.                     commit tran
  10715.                 end
  10716.                 return (1)
  10717.             end
  10718.                 
  10719.             fetch hCarticles into @article
  10720.         end
  10721.         close hCarticles
  10722.         deallocate hCarticles
  10723.     end
  10724.  
  10725.     delete from MSpublications where 
  10726.         publisher_id = @publisher_id and
  10727.         publisher_db = @publisher_db and
  10728.         publication = @publication
  10729.     if @@error <> 0
  10730.     begin
  10731.         if @@trancount > 0
  10732.         begin
  10733.             rollback tran MSdrop_publication
  10734.             commit tran
  10735.         end
  10736.         raiserror (14006, 16, -1)
  10737.         return (1)
  10738.     end
  10739.  
  10740.     -- Drop snapshot agent
  10741.     exec @retcode = dbo.sp_MSdrop_snapshot_agent
  10742.             @publisher = @publisher,
  10743.             @publisher_db = @publisher_db,
  10744.             @publication = @publication
  10745.     if @@ERROR<> 0 or @retcode <> 0
  10746.     begin
  10747.         if @@trancount > 0
  10748.         begin
  10749.             rollback tran MSdrop_publication
  10750.             commit tran
  10751.         end
  10752.         return (1)
  10753.     end
  10754.  
  10755.     -- Drop the logreader agent if
  10756.     -- 1. thirdparty publisher OR 
  10757.     -- 2. no publication left in the publisher database
  10758.     if @thirdparty_flag = 1 OR
  10759.         not exists (select * from MSpublications where 
  10760.             publisher_id = @publisher_id and
  10761.             publisher_db = @publisher_db)
  10762.     begin
  10763.         exec @retcode = dbo.sp_MSdrop_logreader_agent
  10764.                 @publisher = @publisher,
  10765.                 @publisher_db = @publisher_db,
  10766.                 @publication = @publication
  10767.         if @@ERROR<> 0 or @retcode <> 0
  10768.         begin
  10769.             if @@trancount > 0
  10770.             begin
  10771.                 rollback tran MSdrop_publication
  10772.                 commit tran
  10773.             end
  10774.             return (1)
  10775.         end
  10776.     end
  10777.  
  10778.     -- Delete anonymous agents
  10779.     delete MSdistribution_agents where
  10780.         publisher_id = @publisher_id and
  10781.         publisher_db = @publisher_db and
  10782.         publication = @publication
  10783.     if @@ERROR<> 0 or @retcode <> 0
  10784.     begin
  10785.         if @@trancount > 0
  10786.             rollback tran MSdrop_publication
  10787.         return (1)
  10788.     end
  10789.  
  10790.     delete MSmerge_agents where
  10791.         publisher_id = @publisher_id and
  10792.         publisher_db = @publisher_db and
  10793.         publication = @publication
  10794.     if @@ERROR<> 0 or @retcode <> 0
  10795.     begin
  10796.         if @@trancount > 0
  10797.             rollback tran MSdrop_publication
  10798.         return (1)
  10799.     end
  10800.  
  10801.     -- Cleanup publication access list table
  10802.     delete MSpublication_access where
  10803.         publication_id = @publication_id
  10804.     if @@ERROR<> 0 or @retcode <> 0
  10805.     begin
  10806.         if @@trancount > 0
  10807.             rollback tran MSdrop_publication
  10808.         return (1)
  10809.     end
  10810.  
  10811.     -- Remove publisher_id, publisher_db pair if no other publication is using it. 
  10812.     if not exists (select * from MSpublications where publisher_id = @publisher_id and
  10813.         publisher_db = @publisher_db)
  10814.     begin
  10815.         declare @publisher_database_id int
  10816.  
  10817.         select @publisher_database_id = id from MSpublisher_databases where 
  10818.             publisher_id = @publisher_id and 
  10819.             publisher_db = @publisher_db
  10820.  
  10821.         delete from MSrepl_backup_lsns where 
  10822.             publisher_database_id = @publisher_database_id
  10823.  
  10824.         delete from MSpublisher_databases where 
  10825.             publisher_id = @publisher_id and publisher_db = @publisher_db
  10826.         if @@error <> 0
  10827.         begin
  10828.             if @@trancount > 0
  10829.             begin
  10830.                 rollback tran MSdrop_publication
  10831.                 commit tran
  10832.             end
  10833.             return (1)
  10834.         end
  10835.  
  10836.         -- Cleaning up MSrepl_originators
  10837.         delete MSrepl_originators where
  10838.             publisher_database_id = @publisher_database_id
  10839.         if @@error <> 0
  10840.         begin
  10841.             if @@trancount > 0
  10842.                 rollback tran MSdrop_publication
  10843.             return (1)
  10844.         end
  10845.  
  10846.     end
  10847.  
  10848.     commit tran
  10849. go
  10850. raiserror(15339,-1,-1,'sp_MSadd_snapshot_agent')
  10851. GO
  10852. CREATE PROCEDURE sp_MSadd_snapshot_agent (
  10853.     @name nvarchar(100) = NULL,
  10854.     @publisher sysname,
  10855.     @publisher_db sysname,
  10856.     @publication sysname,  
  10857.     @publication_type int = 0,              -- 0 Transactional 1 Snapshot 2 Merge
  10858.     @local_job bit,  
  10859.     @freqtype  int = 4 ,                  /* 4== Daily */
  10860.     @freqinterval int  = 1,             /* Every day */
  10861.     @freqsubtype int =  4,                 /* Sub interval = Minute */
  10862.     @freqsubinterval int = 5,              /* Every five minutes */
  10863.     @freqrelativeinterval int = 1, 
  10864.     @freqrecurrencefactor int = 0, 
  10865.     @activestartdate int = 0,             /* 12:00 am - 11:59 pm */
  10866.     @activeenddate int =99991231 ,         /* No start date */    
  10867.     @activestarttimeofday int = 0,         
  10868.     @activeendtimeofday int = 235959,     /* No end time */    
  10869.     @command nvarchar(4000) = NULL,
  10870.     @job_existing bit = 0,   -- for 6x publisher
  10871.     @snapshot_jobid binary(16) = NULL OUTPUT
  10872. ) AS
  10873.  
  10874.  
  10875.     SET NOCOUNT ON
  10876.  
  10877.     /*
  10878.     ** Declarations.
  10879.     */
  10880.     DECLARE @retcode            int
  10881.     DECLARE @publisher_id       smallint
  10882.     DECLARE @profile_id         int
  10883.     DECLARE @snapshot_type      int
  10884.     DECLARE @databasename       sysname
  10885.     DECLARE @agent_id           int
  10886.  
  10887.     DECLARE @distributor_security_mode      int                     /* 0 standard; 1 integrated */
  10888.     DECLARE @distributor_login              sysname 
  10889.     DECLARE @distributor_password           nvarchar(524)
  10890.     DECLARE @category_name      sysname
  10891.     DECLARE @platform_nt        binary
  10892.  
  10893.     /*
  10894.     ** Initializations
  10895.     */
  10896.     select @platform_nt = 0x1
  10897.  
  10898.     select @publisher_id = srvid from master..sysservers where
  10899.         UPPER(srvname) = UPPER(@publisher)
  10900.  
  10901.     -- Always use integrated security on winNT
  10902.     if (@platform_nt = platform() & @platform_nt)
  10903.         set @distributor_security_mode = 1
  10904.     else
  10905.     begin
  10906.         select  @distributor_security_mode = 0,
  10907.                 @distributor_login  = login,
  10908.                 @distributor_password = password
  10909.             from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername)
  10910.     end
  10911.  
  10912.     select @command = @command + ' -DistributorSecurityMode ' + 
  10913.         convert(nvarchar(10),@distributor_security_mode) +  ' ' 
  10914.     if @distributor_security_mode <> 1
  10915.     begin
  10916.         if @distributor_login is not NULL
  10917.             select @command = @command + '-DistributorLogin ' + @distributor_login + ' '
  10918.         if @distributor_password is not NULL
  10919.             select @command = @command + '-DistributorEncryptedPassword ' + quotename(@distributor_password) + ' '
  10920.     end
  10921.  
  10922.     -- if @name is not null and @job_existing = 1, the proc is from DMO scripting
  10923.     -- check to see if the job is there or not, if not, reset @job_existing
  10924.     -- value. This is for the case when the user generate the script at
  10925.     -- the publisher but did not re-create repl jobs at the distributor.
  10926.     -- We don't want to reset the @name parameter to null here because 
  10927.     -- the user probably expects us to create a job with the given name.
  10928.     if @local_job = 1 and @job_existing = 1 and @name is not null and 
  10929.        @name <> N''
  10930.     begin
  10931.         if not exists (select * from msdb..sysjobs_view where 
  10932.             name = @name and
  10933.             UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName'))))
  10934.         begin
  10935.             set @job_existing = 0
  10936.         end
  10937.     end
  10938.  
  10939.     BEGIN TRAN
  10940.     
  10941.     /* Code for snapshot agent type in MSagent_profiles */
  10942.     SELECT @snapshot_type = 1
  10943.  
  10944.     -- Get the default profile ID for the snapshot agent type. If a third party publication
  10945.     -- no profile is used.
  10946.     if exists (select * from MSpublications where 
  10947.                 publisher_id = @publisher_id and
  10948.                 publisher_db = @publisher_db and
  10949.                 publication = @publication and
  10950.                 thirdparty_flag = 1)
  10951.     begin
  10952.         set @profile_id = 0
  10953.     end
  10954.     else
  10955.     begin
  10956.          SELECT @profile_id = profile_id FROM msdb..MSagent_profiles WHERE 
  10957.             agent_type = @snapshot_type and
  10958.             def_profile = 1
  10959.     end
  10960.  
  10961.  
  10962.     if not exists (select * from MSsnapshot_agents where
  10963.         publisher_id = @publisher_id and
  10964.         publisher_db = @publisher_db and
  10965.         publication = @publication)
  10966.     begin
  10967.         /* 
  10968.         ** Insert row
  10969.         */
  10970.         INSERT INTO MSsnapshot_agents (name, publisher_id, publisher_db, publication, publication_type,
  10971.                                 local_job, profile_id)
  10972.              VALUES ('',@publisher_id, @publisher_db, @publication, @publication_type, @local_job, @profile_id)
  10973.         IF @@ERROR <> 0
  10974.             GOTO UNDO
  10975.  
  10976.         set @agent_id = @@IDENTITY
  10977.     end
  10978.     else
  10979.         select @agent_id = id from MSsnapshot_agents where
  10980.             publisher_id = @publisher_id and
  10981.             publisher_db = @publisher_db and
  10982.             publication = @publication
  10983.  
  10984.     DECLARE @name_is_generated bit
  10985.     SELECT @name_is_generated = 0     
  10986.     IF @name IS NULL OR @name = N''
  10987.     BEGIN
  10988.         SELECT @name_is_generated = 1
  10989.         SELECT @name = CONVERT(nvarchar(28),@publisher ) + '-' + CONVERT(nvarchar(28),@publisher_db) + '-' + 
  10990.                         CONVERT(nvarchar(28),@publication) + '-'  + CONVERT(nvarchar, @agent_id)
  10991.     END
  10992.  
  10993.     -- If the generated name already exists, re-generate the name with a 
  10994.     -- guid appended
  10995.     IF @name_is_generated = 1
  10996.     BEGIN
  10997.         IF EXISTS (SELECT * FROM msdb..sysjobs_view 
  10998.                     WHERE name = @name 
  10999.                       AND UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName'))))
  11000.         BEGIN
  11001.             SELECT @name = fn_repluniquename(newid(), @publisher, @publisher_db, 
  11002.                 @publication, null)
  11003.         END            
  11004.     END
  11005.  
  11006.     -- Add Perfmon instance
  11007.     dbcc addinstance ("SQL Replication Snapshot", @name)
  11008.  
  11009.     IF @local_job = 1 and @job_existing = 0
  11010.     BEGIN
  11011.  
  11012.     -- ********WORKAROUND********
  11013.         DECLARE @nullchar nchar(20)
  11014.         SELECT @nullchar = NULL
  11015.     -- ********WORKAROUND********
  11016.  
  11017.         set @databasename = db_name()
  11018.         -- Get Snapshot category name (assumes category_id = 15)
  11019.         select @category_name = name FROM msdb.dbo.syscategories where category_id = 15
  11020.  
  11021.         EXECUTE @retcode = dbo.sp_MSadd_repl_job 
  11022.             @name = @name, 
  11023.             @subsystem = 'Snapshot', 
  11024.             @server = @publisher, 
  11025.             @databasename = @databasename, 
  11026.             @enabled = 1, 
  11027.             @freqtype = @freqtype, 
  11028.             @freqinterval = @freqinterval, 
  11029.             @freqsubtype = @freqsubtype, 
  11030.             @freqsubinterval = @freqsubinterval, 
  11031.             @freqrelativeinterval = @freqrelativeinterval, 
  11032.             @freqrecurrencefactor = @freqrecurrencefactor, 
  11033.             @activestartdate = @activestartdate, 
  11034.             @activeenddate = @activeenddate, 
  11035.             @activestarttimeofday = @activestarttimeofday, 
  11036.             @activeendtimeofday = @activeendtimeofday, 
  11037.             @nextrundate = 0,
  11038.             @nextruntime = 0,
  11039.             @runpriority = 0,
  11040.             @emailoperatorname = @nullchar,
  11041.             @retryattempts = 10, 
  11042.             @retrydelay = 1, 
  11043.             @command = @command, 
  11044.             @loghistcompletionlevel = 0, 
  11045.             @emailcompletionlevel = 0, 
  11046.             @description = @nullchar,
  11047.             @tagadditionalinfo = @nullchar,
  11048.             @tagobjectid = 0, 
  11049.             @tagobjecttype = 0, 
  11050.             @category_name = @category_name,
  11051.             @failure_detection = 1,
  11052.             @agent_id = @agent_id,
  11053.             @job_id = @snapshot_jobid OUTPUT
  11054.  
  11055.   
  11056.        IF @@ERROR <> 0 or @retcode <> 0
  11057.             GOTO UNDO
  11058.     END
  11059.  
  11060.     if @local_job = 1 and @job_existing = 1 
  11061.     begin
  11062.         if @snapshot_jobid is null
  11063.         begin
  11064.             select @snapshot_jobid = job_id from msdb..sysjobs_view where 
  11065.                 name = @name and
  11066.                 UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName')))
  11067.             if @snapshot_jobid IS NULL
  11068.             begin
  11069.                 -- Message from msdb.dbo.sp_verify_job_identifiers
  11070.                 RAISERROR(14262, -1, -1, 'Job', @name)          
  11071.                 GOTO UNDO
  11072.             end
  11073.         end
  11074.         else
  11075.         begin
  11076.             if not exists (select * from msdb..sysjobs_view where 
  11077.                 job_id = @snapshot_jobid and
  11078.                 UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName'))))
  11079.             begin
  11080.                 -- Message from msdb.dbo.sp_verify_job_identifiers
  11081.                 RAISERROR(14262, -1, -1, 'Job', @name)          
  11082.                 GOTO UNDO
  11083.             end
  11084.         end
  11085.     end
  11086.  
  11087. /* Moved up
  11088.     -- Get the job id if it already exists
  11089.     if @local_job = 1 and @job_existing = 1 
  11090.     begin
  11091.         select @snapshot_jobid = job_id from msdb..sysjobs_view where 
  11092.             job_id = @snapshot_jobid and
  11093.             UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName')))
  11094.         if @snapshot_jobid IS NULL
  11095.         begin
  11096.             -- Message from msdb.dbo.sp_verify_job_identifiers
  11097.             RAISERROR(14262, -1, -1, 'Job', @name)          
  11098.             GOTO UNDO
  11099.         end
  11100.     end
  11101. */
  11102.  
  11103.     -- Generate a job GUID for remote agents. This will be used by the UI to uniquely
  11104.     -- identify rows returned by the enums
  11105.     if @local_job = 0
  11106.     begin
  11107.         -- Third party publication will pass in snapshot agent name which is created as
  11108.         -- a SQLServerAgent job.
  11109.         if @name is not null 
  11110.             select @snapshot_jobid = job_id from msdb..sysjobs_view where
  11111.                 name = @name
  11112.         if @snapshot_jobid is null
  11113.             set @snapshot_jobid = newid()
  11114.         -- Reset @local_job to 1 so that repl monitor can start the job.
  11115.         -- In sp_MSdrop_snapshot_agent, we will not drop the job if the publication 
  11116.         -- is from third party.
  11117.         else
  11118.             set @local_job = 1
  11119.     end
  11120.  
  11121.     -- Caution: @local job might be changed from the passed in value.
  11122.     UPDATE MSsnapshot_agents SET 
  11123.         name = @name,
  11124.         job_id = @snapshot_jobid,
  11125.         -- Update the following fields because the row maybe added before this sp call
  11126.         -- by sp_MSadd_publication.
  11127.         publication_type = @publication_type,
  11128.         local_job = @local_job, 
  11129.         profile_id = @profile_id
  11130.         WHERE
  11131.         id = @agent_id
  11132.  
  11133.     IF @@ERROR <> 0
  11134.         GOTO UNDO
  11135.  
  11136.     -- Update global replication status table
  11137.     EXEC dbo.sp_MSupdate_replication_status
  11138.         @publisher,
  11139.         @publisher_db,
  11140.         @publication,
  11141.         @publication_type,
  11142.         @agent_type = 1,
  11143.         @agent_name = @name,
  11144.         @status = 0     -- not running status
  11145.  
  11146.     COMMIT TRAN
  11147.  
  11148.     RETURN(0)
  11149.  
  11150. UNDO:
  11151.     if @@TRANCOUNT = 1
  11152.         ROLLBACK TRAN
  11153.     else
  11154.         COMMIT TRAN
  11155.     return(1)
  11156. GO
  11157.  
  11158. raiserror(15339,-1,-1,'sp_MSadd_logreader_agent')
  11159. GO
  11160. CREATE PROCEDURE sp_MSadd_logreader_agent (
  11161.     @name nvarchar(100) = NULL,
  11162.     @publisher sysname,
  11163.     @publisher_db sysname,
  11164.     @publication sysname,   --Only used by 3rd party publisher
  11165.     @local_job bit,
  11166.     @job_existing bit = 0,
  11167.     @job_id binary(16) = NULL
  11168. ) AS
  11169.  
  11170.  
  11171.     SET NOCOUNT ON
  11172.  
  11173.     /*
  11174.     ** Declarations.
  11175.     */
  11176.     DECLARE @retcode            int
  11177.     DECLARE @agent_args         nvarchar(255)
  11178.     DECLARE @publisher_id       smallint
  11179.     DECLARE @profile_id         int
  11180.     DECLARE @logreader_type     int
  11181.     DECLARE @databasename       sysname
  11182.     DECLARE @agent_id           int
  11183.     DECLARE @distributor_security_mode      int                     /* 0 standard; 1 integrated */
  11184.     DECLARE @distributor_login              sysname 
  11185.     DECLARE @distributor_password           nvarchar(524)
  11186.     DECLARE @category_name      sysname
  11187.     DECLARE @platform_nt binary
  11188.  
  11189.     /*
  11190.     ** Initializations
  11191.     */
  11192.     select @platform_nt = 0x1
  11193.  
  11194.     select @publisher_id = srvid from master..sysservers where
  11195.         UPPER(srvname) = UPPER(@publisher)
  11196.     
  11197.     -- Always use integrated security on winNT
  11198.     if (@platform_nt = platform() & @platform_nt)
  11199.         set @distributor_security_mode = 1
  11200.     else
  11201.     begin
  11202.         select  @distributor_security_mode = 0,
  11203.                 @distributor_login  = login,
  11204.                 @distributor_password = password
  11205.             from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername)
  11206.     end
  11207.  
  11208.     -- if @name is not null and @job_existing = 1, the proc is from DMO scripting
  11209.     -- check to see if the job is there are not, if not, reset @job_existing and
  11210.     -- @name values. This is for the case when the user generate the script at
  11211.     -- the publisher but did not re-create repl jobs at the distributor.
  11212.     if @local_job = 1 and @job_existing = 1 and @name is not null and 
  11213.        @name <> N''
  11214.     begin
  11215.         if not exists (select * from msdb..sysjobs_view where 
  11216.             name = @name and
  11217.             UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName'))))
  11218.         begin
  11219.             set @job_existing = 0
  11220.             set @name = null
  11221.         end
  11222.     end
  11223.  
  11224.     BEGIN TRAN
  11225.  
  11226.     -- If creating locally, try to drop it first
  11227.     IF @local_job = 1 and @job_existing = 0
  11228.     begin
  11229.         EXEC dbo.sp_MSdrop_logreader_agent 
  11230.             @publisher = @publisher,
  11231.             @publisher_db = @publisher_db,
  11232.             @publication = @publication  
  11233.         IF @@ERROR <> 0
  11234.             GOTO UNDO
  11235.     end
  11236.  
  11237.     /* Code for log reader agent type in MSagent_profiles */
  11238.     SELECT @logreader_type = 2
  11239.  
  11240.     -- Get the default profile ID for the logreader agent type. If a third party publication
  11241.     -- no profile is used.
  11242.     if exists (select * from MSpublications where 
  11243.                 publisher_id = @publisher_id and
  11244.                 publisher_db = @publisher_db and
  11245.                 publication = @publication and
  11246.                 thirdparty_flag = 1)
  11247.     begin
  11248.         set @profile_id = 0
  11249.     end
  11250.     else
  11251.     begin
  11252.         SELECT @profile_id = profile_id FROM msdb..MSagent_profiles WHERE 
  11253.             agent_type = @logreader_type and
  11254.             def_profile = 1
  11255.     end
  11256.  
  11257.     /* 
  11258.     ** Insert row
  11259.     */
  11260.     INSERT INTO MSlogreader_agents (name, publisher_id, publisher_db, publication, 
  11261.                     local_job, profile_id)
  11262.          VALUES ('',@publisher_id, @publisher_db, @publication, @local_job, @profile_id)
  11263.     IF @@ERROR <> 0
  11264.         GOTO UNDO
  11265.  
  11266.     set @agent_id = @@IDENTITY
  11267.         
  11268.     DECLARE @name_is_generated bit
  11269.     SELECT @name_is_generated = 0     
  11270.     IF @name IS NULL OR @name = N''
  11271.     BEGIN
  11272.         SELECT @name_is_generated = 1
  11273.         SELECT @name = CONVERT(nvarchar(43),@publisher ) + '-' + CONVERT(nvarchar(43),@publisher_db) + '-' + CONVERT(nvarchar, @@IDENTITY)
  11274.     END
  11275.  
  11276.     -- If the generated name already exists, re-generate the name with a 
  11277.     -- guid appended
  11278.     IF @name_is_generated = 1
  11279.     BEGIN
  11280.         IF EXISTS (SELECT * FROM msdb..sysjobs_view 
  11281.                     WHERE name = @name 
  11282.                       AND UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName'))))
  11283.         BEGIN
  11284.             SELECT @name = fn_repluniquename(newid(), @publisher, @publisher_db, null, null)
  11285.         END            
  11286.     END
  11287.     
  11288.     -- Add Perfmon instance
  11289.     dbcc addinstance ("SQL Replication Logreader", @name)
  11290.  
  11291.     IF @local_job = 1 and @job_existing = 0
  11292.     BEGIN            
  11293.         SELECT @agent_args = '-Publisher ' + QUOTENAME(@publisher)
  11294.         SELECT @agent_args = @agent_args + ' -PublisherDB ' + QUOTENAME(@publisher_db)
  11295.         SELECT @agent_args = @agent_args + ' -Distributor ' + QUOTENAME(@@SERVERNAME)
  11296.  
  11297.         select @agent_args = @agent_args + ' -DistributorSecurityMode ' + 
  11298.             convert(nvarchar(10),@distributor_security_mode) +  ' ' 
  11299.         if @distributor_security_mode <> 1
  11300.         begin
  11301.             if @distributor_login is not NULL
  11302.                 select @agent_args = @agent_args + '-DistributorLogin ' + @distributor_login + ' '
  11303.             if @distributor_password is not NULL
  11304.                 select @agent_args = @agent_args + '-DistributorEncryptedPassword ' + quotename(@distributor_password) + ' '
  11305.         end
  11306.  
  11307. --    *******WORKAROUND*******
  11308.         DECLARE @nullchar nchar(20)
  11309.         SELECT @nullchar = NULL
  11310. --    *******WORKAROUND*******
  11311.  
  11312.         set @databasename = db_name()
  11313.         -- Get Logreader category name (assumes category_id = 13)
  11314.         select @category_name = name FROM msdb.dbo.syscategories where category_id = 13
  11315.  
  11316.         EXECUTE @retcode = dbo.sp_MSadd_repl_job
  11317.         @name = @name,
  11318.         @subsystem = 'LogReader',
  11319.         @server = @publisher,
  11320.         @databasename = @databasename,
  11321.         @enabled = 1,
  11322.         @freqtype = 64,       /* Auto-Start */
  11323.         @freqinterval                   = 1,
  11324.         @freqsubtype                    = 1,
  11325.         @freqsubinterval                = 1,
  11326.         @freqrelativeinterval= 1,
  11327.         @freqrecurrencefactor   = 1,
  11328.         @activestartdate                = 0,
  11329.         @activeenddate                  = 0,
  11330.         @activestarttimeofday   = 0,
  11331.         @activeendtimeofday     = 0,
  11332.         @nextrundate                    = 12355,
  11333.         @nextruntime                    = 13423,
  11334.         @runpriority                    = 0,
  11335.         @emailoperatorname              = @nullchar,
  11336.         @retryattempts = 10,            
  11337.         @retrydelay = 1,    
  11338.         @command = @agent_args,
  11339.         @loghistcompletionlevel = 0,
  11340.         @category_name = @category_name,
  11341.         @failure_detection = 1,
  11342.         @agent_id = @agent_id,
  11343.         @job_id = @job_id OUTPUT
  11344.  
  11345.   
  11346.        IF @@ERROR <> 0 or @retcode <> 0
  11347.             GOTO UNDO
  11348.     END
  11349.  
  11350.     if @local_job = 1 and @job_existing = 1 
  11351.     begin
  11352.         if @job_id is null
  11353.         begin
  11354.             select @job_id = job_id from msdb..sysjobs_view where 
  11355.                 name = @name and
  11356.                 UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName')))
  11357.             if @job_id IS NULL
  11358.             begin
  11359.                 -- Message from msdb.dbo.sp_verify_job_identifiers
  11360.                 RAISERROR(14262, -1, -1, 'Job', @name)          
  11361.                 GOTO UNDO
  11362.             end
  11363.         end
  11364.         else
  11365.         begin
  11366.             if not exists (select * from msdb..sysjobs_view where 
  11367.                 job_id = @job_id and
  11368.                 UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName'))))
  11369.             begin
  11370.                 -- Message from msdb.dbo.sp_verify_job_identifiers
  11371.                 RAISERROR(14262, -1, -1, 'Job', @name)          
  11372.                 GOTO UNDO
  11373.             end
  11374.         end
  11375.     end
  11376.  
  11377.     -- Generate a job GUID for remote agents. This will be used by the UI to uniquely
  11378.     -- identify rows returned by the enums
  11379.     if @local_job = 0
  11380.     begin
  11381.         -- Third party publication will pass in logreader agent name which is created as
  11382.         -- a SQLServerAgent job.
  11383.         if @name is not null 
  11384.             select @job_id = job_id from msdb..sysjobs_view where
  11385.                 name = @name
  11386.         if @job_id is null
  11387.             set @job_id = newid()
  11388.         -- Reset @local_job to 1 so that repl monitor can start the job.
  11389.         -- In sp_MSdrop_logreader_agent, we will not drop the job if the publication 
  11390.         -- is from third party.
  11391.         else
  11392.             set @local_job = 1
  11393.     end
  11394.  
  11395.     UPDATE MSlogreader_agents SET name = @name,
  11396.         job_id = @job_id WHERE
  11397.         id = @agent_id
  11398.     IF @@ERROR <> 0
  11399.         GOTO UNDO
  11400.  
  11401.     -- Update global replication status table
  11402.     EXEC dbo.sp_MSupdate_replication_status
  11403.         @publisher,
  11404.         @publisher_db,
  11405.         @publication,
  11406.         @agent_type = 2,
  11407.         @agent_name = @name,
  11408.         @status = 0     -- not running status
  11409.  
  11410.  
  11411.     COMMIT TRAN
  11412.  
  11413.     RETURN(0)
  11414.  
  11415. UNDO:
  11416.     if @@TRANCOUNT = 1
  11417.         ROLLBACK TRAN
  11418.     else
  11419.         COMMIT TRAN
  11420.     return(1)
  11421. GO
  11422.  
  11423. raiserror(15339,-1,-1,'sp_MSadd_publication')
  11424. go
  11425. CREATE PROCEDURE sp_MSadd_publication (
  11426.     @publisher sysname,
  11427.     @publisher_db sysname,
  11428.     @publication sysname,
  11429.     @publication_id int = 0,                    -- REMOVE
  11430.     @publication_type int = 1,                  -- 0 = Transactional 1 = Snapshot  2 = Merge
  11431.     @independent_agent bit = 0,
  11432.     @immediate_sync bit = 0,
  11433.     @allow_push bit = 1,
  11434.     @allow_pull bit = 0,
  11435.     @allow_anonymous bit = 0,
  11436.     @snapshot_agent nvarchar(100) = NULL,
  11437.     @logreader_agent nvarchar (100) = NULL,
  11438.     @description nvarchar(255) = NULL,
  11439.     @retention int =60,
  11440.     @vendor_name nvarchar(100) = 'Microsoft SQL Server',
  11441.     @sync_method int = 0,
  11442.     @allow_subscription_copy bit = 0,
  11443.     @thirdparty_options int = NULL,
  11444.      @allow_queued_tran bit = 0,
  11445.      @queue_type int = NULL
  11446. )
  11447. as
  11448. BEGIN
  11449.     set nocount on
  11450.  
  11451.     declare @thirdparty_flag bit                    -- 0 = SQL Server 1 = Third Party
  11452.             ,@publisher_id smallint
  11453.             ,@retcode int
  11454.             ,@platform_nt binary
  11455.             ,@platform_desktop int
  11456.             ,@agentname nvarchar(100)
  11457.             ,@max_distretention int
  11458.  
  11459.     select @platform_nt = 0x1
  11460.             ,@platform_desktop = 0x100
  11461.  
  11462.     -- Check if publisher is a defined as a distribution publisher in the current database
  11463.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  11464.     if @retcode <> 0
  11465.     begin
  11466.         return(1)
  11467.     end
  11468.  
  11469.     EXEC @retcode = sp_helpdistributor @max_distretention = @max_distretention OUTPUT
  11470.     if @retcode <>0
  11471.     begin
  11472.         return (1)
  11473.     end
  11474.  
  11475.     -- Get third party flag
  11476.     select @thirdparty_flag = thirdparty_flag from msdb..MSdistpublishers
  11477.         where UPPER(name) = UPPER(@publisher)
  11478.     
  11479.     /*
  11480.     ** Parameter Check: @publication. (For 3rd party publications.)
  11481.     ** The @publication name must conform to the rules for identifiers,
  11482.     ** and must not be the keyword 'all'.
  11483.     */
  11484.  
  11485.     IF @publication IS NULL
  11486.         BEGIN
  11487.             RAISERROR (14043, 16, -1, '@publication')
  11488.             RETURN (1)
  11489.         END
  11490.  
  11491.     exec @retcode = dbo.sp_MSreplcheck_name @publication
  11492.     if @@ERROR <> 0 or @retcode <> 0
  11493.         return(1)
  11494.  
  11495.     IF LOWER (@publication) = 'all'
  11496.         BEGIN
  11497.             RAISERROR (14034, 16, -1)
  11498.             RETURN (1)
  11499.         END
  11500.  
  11501.  
  11502.     -- Parameter Check: @publication_type
  11503.     -- Make sure that the publication type is one of the following:
  11504.     -- 0  transactional
  11505.     -- 1  snapshot
  11506.     -- 2  merge
  11507.     if @publication_type not in (0,1,2)
  11508.     begin
  11509.         raiserror(20033, 16, -1)
  11510.         return (1)
  11511.     end
  11512.  
  11513.     -- disable tran/queued publishing on Win9x
  11514.     if (@publication_type = 0 or @allow_queued_tran = 1) and (platform() & @platform_nt != @platform_nt)
  11515.     begin
  11516.         -- Note 21052 was deleted and then changed. This message should go into messages.sql post shiloh
  11517.         --raiserror(21052, 16, -1)
  11518.         raiserror('Distributor for transactional or queued publications has to run on Windows NT platforms only.', 16, 1)
  11519.         return (1)
  11520.     end
  11521.  
  11522.     if (@publication_type = 0) and (platform() & @platform_desktop = @platform_desktop)
  11523.     begin
  11524.         raiserror(21108, 16, -1)
  11525.         return (1)
  11526.     end
  11527.  
  11528.     -- Parameter Check: @immediate_sync
  11529.     -- The publication must support independent_agent to support immediate_sync
  11530.     if @immediate_sync = 1 and @independent_agent != 1
  11531.     begin
  11532.         raiserror(21022, 16, -1)
  11533.         return (1)
  11534.     end
  11535.  
  11536.     -- Parameter Check: @allow_anonymous
  11537.     -- The publication must support immediate_sync to support anonymous.
  11538.     if @allow_anonymous = 1 and @immediate_sync != 1
  11539.     begin
  11540.         raiserror(20011, 16, -1)
  11541.         return (1)
  11542.     end
  11543.     
  11544.     -- Make sure publication does not already exist
  11545.     if exists (select * from MSpublications where publication = @publication and
  11546.         publisher_id = @publisher_id and publisher_db = @publisher_db)
  11547.     begin
  11548.         if @thirdparty_flag = 1
  11549.         begin
  11550.             raiserror(14016, 16, -1, @publication)
  11551.             return (1)
  11552.         end
  11553.         else
  11554.         begin
  11555.             exec @retcode = dbo.sp_MSdrop_publication 
  11556.                 @publisher = @publisher,
  11557.                 @publisher_db = @publisher_db,
  11558.                 @publication = @publication
  11559.             if @@error <> 0 or @retcode <> 0
  11560.                 return (1)
  11561.         end
  11562.     end
  11563.  
  11564.      --
  11565.      -- For MSMQ queue type - Distributor needs to support MSMQ 2.0
  11566.      --
  11567.      if (@queue_type = 1 and @allow_queued_tran = 1)
  11568.      begin
  11569.          --
  11570.          -- Now we use xp_MSver to detect NT OS version
  11571.          -- MSMQ subscription only allowed for platforms that support MSMQ 2.0
  11572.          -- version 5.0.2195 or higher
  11573.          --
  11574.          create table #tosversion ( propid int, propname sysname collate database_default, value int, charvalue nvarchar(255) collate database_default)
  11575.          insert into #tosversion (propid, propname, value, charvalue)
  11576.              exec master.dbo.xp_msver N'WindowsVersion'
  11577.  
  11578.          declare @vervalue int
  11579.              ,@lobyte tinyint
  11580.              ,@hibyte tinyint
  11581.              ,@loword smallint
  11582.              ,@hiword smallint
  11583.  
  11584.          --
  11585.          -- low order byte of low order word = OSmajor, high order byte of low order word = OSminor
  11586.          -- high order word = OSbuild
  11587.          --
  11588.          select @vervalue = value from #tosversion where propname = N'WindowsVersion'
  11589.          select @loword = (@vervalue & 0xffff)
  11590.                  ,@hiword = (@vervalue / 0x10000) & 0xffff
  11591.          select @lobyte = @loword & 0xff
  11592.                  ,@hibyte = (@loword / 100) & 0xff
  11593.          drop table #tosversion
  11594.  
  11595.          --
  11596.          -- check for OS major version
  11597.          --
  11598.          if (@lobyte < 5)
  11599.          begin
  11600.              raiserror(21334, 16, 4, '2.0')
  11601.              return (1)
  11602.          end
  11603.  
  11604.          --
  11605.          -- check for OS build version
  11606.          --
  11607.          if (@lobyte = 5 and @hiword < 2195)
  11608.          begin
  11609.              raiserror(21334, 16, 5, '2.0')
  11610.              return (1)
  11611.          end
  11612.      end
  11613.     
  11614.     begin tran
  11615.     save tran MSadd_publication
  11616.  
  11617.     insert into MSpublications values (@publisher_id, @publisher_db, @publication, 
  11618.         @publication_type, @thirdparty_flag, @independent_agent, @immediate_sync, @allow_push,
  11619.         @allow_pull, @allow_anonymous, @description, @vendor_name, @retention, 
  11620.         @sync_method, @allow_subscription_copy, @thirdparty_options, @allow_queued_tran)
  11621.     if @@error <> 0
  11622.         goto UNDO
  11623.  
  11624.     -- Enable the distribution cleanup agent if transactional or snapshot publicational
  11625.     if @publication_type = 0 or @publication_type = 1
  11626.     begin
  11627.         select @agentname = name from msdb..sysjobs j, msdb..sysjobsteps s where 
  11628.             j.job_id = s.job_id and
  11629.             j.category_id = 11 and
  11630.             s.database_name = db_name()
  11631.  
  11632.         exec @retcode = msdb.dbo.sp_update_job @job_name=@agentname, @enabled=1
  11633.         if @@error <> 0 or @retcode <> 0
  11634.             goto UNDO
  11635.     end
  11636.  
  11637.     -- Add snapshot and logreader agent
  11638.     
  11639.     -- Always add a non local snapshot agent. This is to cover the case
  11640.     -- when there's no SQLServerAgent job for the snapshot agent (For example, in Access).
  11641.     -- The agent entry is needed for initance check.
  11642.     -- sp_addpublication_snapshot will drop the entry and recreat it.
  11643.     exec @retcode = dbo.sp_MSadd_snapshot_agent
  11644.         @name = @snapshot_agent,
  11645.         @publisher = @publisher,
  11646.         @publisher_db = @publisher_db,
  11647.         @publication = @publication,
  11648.         @publication_type = @publication_type,
  11649.         @local_job = 0
  11650.     if @@error <> 0 or @retcode <> 0
  11651.         goto UNDO
  11652.  
  11653.  
  11654.     -- If null is passed in, we know that the agent is created already. (For SQL server).
  11655.     -- If not null is passed in, add the agents without creating local jobs (For third party).
  11656.     if @logreader_agent is not null
  11657.     begin
  11658.         exec @retcode = dbo.sp_MSadd_logreader_agent
  11659.             @name = @logreader_agent,
  11660.             @publisher = @publisher,
  11661.             @publisher_db = @publisher_db,
  11662.             @publication = @publication,
  11663.             @local_job = 0
  11664.         if @@error <> 0 or @retcode <> 0
  11665.             goto UNDO
  11666.     end
  11667.  
  11668.     -- If publisher_id, publisher_db pair is not in MSpublisher_databases then add it.  This will be used
  11669.     -- to store a publisher_database_id in the MSrepl_transactions and MSrepl_commands table.
  11670.     if not exists (select * from MSpublisher_databases where publisher_id = @publisher_id and
  11671.         publisher_db = @publisher_db)
  11672.     begin
  11673.         insert into MSpublisher_databases (publisher_id, publisher_db) values (@publisher_id, @publisher_db)
  11674.         if @@error <> 0
  11675.             goto UNDO
  11676.         insert into MSrepl_backup_lsns (publisher_database_id) values (@@identity)
  11677.         if @@error <> 0
  11678.             goto UNDO
  11679.     end
  11680.  
  11681.     commit tran
  11682.  
  11683.     return(0)
  11684.  
  11685. UNDO:
  11686.     if @@TRANCOUNT > 0
  11687.     begin
  11688.         ROLLBACK TRAN MSadd_publication
  11689.         COMMIT TRAN
  11690.     end
  11691.     return(1)
  11692. END
  11693. GO
  11694.  
  11695. /* 
  11696. **  History runstatus values defined in sqlrepl.h
  11697. **
  11698. **  Start       1
  11699. **  Succeed     2
  11700. **  Inprogress  3
  11701. **  Idle        4
  11702. **  Retry       5
  11703. **  Failure     6
  11704. */
  11705. GO
  11706.  
  11707. raiserror(15339,-1,-1,'sp_MSrepl_raiserror')
  11708. go
  11709. create proc sp_MSrepl_raiserror
  11710. @agent sysname,
  11711. @agent_name nvarchar(100),
  11712. @status int,
  11713. @message nvarchar(255),
  11714. @subscriber sysname = NULL,
  11715. @publication sysname = NULL,
  11716. @article sysname = NULL
  11717. as
  11718.     if @status = 2      --Succeeded
  11719.         raiserror (14150, 10, -1, @agent, @agent_name, @message)
  11720.     else if @status = 5 --Retry Failure
  11721.         raiserror (14152, 10, -1, @agent, @agent_name, @message)
  11722.     else if @status = 6 --Failure
  11723.     begin
  11724.         raiserror (14151, 18, -1, @agent, @agent_name, @message)
  11725.     end
  11726.     else if @status = 7
  11727.     begin
  11728.         raiserror (20574, 10, -1, @subscriber, @article, @publication)
  11729.     end
  11730.     else if @status = 8
  11731.     begin
  11732.         raiserror (20575, 10, -1, @subscriber, @article, @publication)
  11733.     end
  11734.     else if @status = 9
  11735.     begin
  11736.         raiserror (14158, 10, -1, @agent, @agent_name, @message)
  11737.     end
  11738. go
  11739.  
  11740. raiserror(15339,-1,-1,'sp_MSget_new_errorid')
  11741. GO
  11742.  
  11743. CREATE PROCEDURE sp_MSget_new_errorid
  11744. @errorid int OUTPUT,
  11745. @xact_seqno varbinary(16) = NULL,
  11746. @command_id int = NULL
  11747. AS
  11748.     set nocount on
  11749.  
  11750.     SELECT @errorid = NULL
  11751.  
  11752.     BEGIN TRAN sp_MSget_new_errorid
  11753.  
  11754.     SET ROWCOUNT 1
  11755.     SELECT @errorid = id FROM MSrepl_errors (UPDLOCK PAGLOCK)
  11756.         ORDER BY id DESC
  11757.     SET ROWCOUNT 0
  11758.  
  11759.     IF @errorid IS NULL
  11760.         SELECT @errorid = 1
  11761.     ELSE
  11762.         SELECT @errorid = @errorid + 1
  11763.  
  11764.     INSERT INTO MSrepl_errors VALUES (@errorid, 
  11765.         GETDATE(), NULL, /* Error with type NULL is placeholder, refer to sp_MSget_repl_error */
  11766.         NULL, NULL, NULL, NULL, @xact_seqno, @command_id)
  11767.  
  11768.     /* return an 0 error_id if failed to insert the row */
  11769.     IF @@ERROR <> 0
  11770.         SELECT @errorid = 0
  11771.  
  11772.     SELECT @errorid
  11773.  
  11774.     COMMIT TRAN
  11775. GO   
  11776.  
  11777. raiserror(15339,-1,-1,'sp_MSadd_qreader_history')
  11778. go
  11779. CREATE PROCEDURE sp_MSadd_qreader_history (
  11780.     @agent_id int,
  11781.     @pubid int = NULL,
  11782.     @runstatus int, 
  11783.     @comments nvarchar(255) = NULL,
  11784.     @transaction_id nvarchar(40) = NULL,
  11785.     @transaction_status int = 0,
  11786.     @transactions_processed int =0,
  11787.     @commands_processed int = 0,
  11788.     @seconds_elapsed int = 0,
  11789.     @subscriber sysname = NULL,
  11790.     @subscriberdb sysname = NULL,
  11791.     @perfmon_increment bit = 1,
  11792.     @log_error bit = 0,
  11793.     @update_existing_row bit = 0,
  11794.     @do_raiserror bit = 1)
  11795. AS
  11796. BEGIN
  11797.     DECLARE @current_time datetime
  11798.             ,@start_time datetime
  11799.             ,@duration int
  11800.             ,@agent_name nvarchar(100)
  11801.             ,@publisher sysname
  11802.             ,@publisher_db sysname
  11803.             ,@publication sysname
  11804.             ,@lastrow_timestamp timestamp
  11805.             ,@retcode int
  11806.             ,@cmdprocessed_rate float
  11807.             ,@transaction_rate float
  11808.             ,@error_id int
  11809.             ,@idle int
  11810.             ,@succeed int
  11811.             ,@startup int
  11812.             ,@retry int
  11813.             ,@failure int
  11814.             ,@inprogress int
  11815.             ,@database sysname
  11816.             ,@statobjid int
  11817.             ,@agentclassname sysname
  11818.  
  11819.     --
  11820.     -- Status const defined in sqlrepl.h 
  11821.     --
  11822.     select @startup = 1
  11823.             ,@succeed = 2
  11824.             ,@inprogress = 3
  11825.             ,@idle = 4
  11826.             ,@retry = 5
  11827.             ,@failure = 6
  11828.  
  11829.     -- intializations
  11830.     if (@pubid = 0)
  11831.         select @pubid = NULL
  11832.     if (@comments = '')
  11833.         select @comments = NULL
  11834.     if (@transaction_id = '')
  11835.         select @transaction_id = NULL
  11836.     if (@commands_processed is NULL)
  11837.         select @commands_processed = 0
  11838.     if (@subscriber = '')
  11839.         select @subscriber = NULL
  11840.     if (@subscriberdb = '')
  11841.         select @subscriberdb = NULL        
  11842.  
  11843.     SELECT @database = db_name()
  11844.             ,@current_time = GETDATE()
  11845.  
  11846.     -- Get named information
  11847.     select @agent_name = name from MSqreader_agents where id = @agent_id
  11848.     if (@agent_name IS NULL)
  11849.     begin
  11850.         --
  11851.         -- When Queue reader is shutting down due to the last queued subscription
  11852.         -- being dropped it may happen that before the Queue reader logs the shutdown 
  11853.         -- message, the subscription drop process deletes the agent entry from MSqreader_agents
  11854.         --
  11855.         select @agent_name = quotename(@@servername) + '.' + cast(db_id() as nvarchar)
  11856.     end
  11857.     if (@pubid is NULL)
  11858.     begin
  11859.         select @publisher = NULL
  11860.                 ,@publisher_db = NULL
  11861.                 ,@publication = NULL
  11862.     end
  11863.     else
  11864.     begin
  11865.         select @publisher = a.srvname, @publisher_db = b.publisher_db, @publication = b.publication
  11866.         from master..sysservers a, MSpublications b
  11867.         where
  11868.             b.publisher_id= @pubid and
  11869.             b.publisher_id = a.srvid
  11870.     end
  11871.  
  11872.     -- Update Perfmon counter
  11873.     if @perfmon_increment = 1
  11874.     begin
  11875.         if @runstatus = @startup
  11876.             dbcc incrementinstance ("SQL Replication Agents", "Running", "QueueReader", 1)
  11877.         else if (@runstatus = @succeed or @runstatus = @retry or @runstatus = @failure)
  11878.             dbcc incrementinstance ("SQL Replication Agents", "Running", "QueueReader", -1)
  11879.     end
  11880.  
  11881.     -- Get start_time for latest agent run
  11882.     IF (@runstatus = @startup)
  11883.         SELECT @start_time = @current_time
  11884.     ELSE
  11885.     BEGIN
  11886.         SELECT TOP 1 @start_time = start_time, @lastrow_timestamp = timestamp
  11887.         FROM MSqreader_history (rowlock)
  11888.         WHERE 
  11889.         agent_id = @agent_id
  11890.         ORDER BY timestamp DESC
  11891.  
  11892.         if (@start_time is NULL)
  11893.         begin
  11894.             select @runstatus = @startup,
  11895.                 @start_time = @current_time
  11896.         end
  11897.     END
  11898.  
  11899.     -- Calculate agent run duration
  11900.     SELECT @duration = DATEDIFF(second, @start_time, @current_time) 
  11901.  
  11902.     -- Calculate rate of processing
  11903.     IF (@seconds_elapsed IS NOT NULL and @seconds_elapsed > 0)
  11904.     BEGIN
  11905.         SELECT @cmdprocessed_rate = (@commands_processed * 1.0)/@seconds_elapsed
  11906.                 ,@transaction_rate = (@transactions_processed * 1.0)/@seconds_elapsed
  11907.     END
  11908.     ELSE
  11909.     BEGIN
  11910.         SELECT @cmdprocessed_rate = 0.0
  11911.                 ,@transaction_rate = 0.0
  11912.     END
  11913.  
  11914.     -- Set Perfmon counters
  11915.     if @runstatus = @idle or @runstatus = @inprogress
  11916.     begin
  11917.         dbcc addinstance ("SQL Replication QueueReader", @agent_name)
  11918. --        dbcc incrementinstance ("SQL Replication QueueReader", "QueueReader:Delivered Cmds/sec", @agent_name, @cmdprocessed_rate)
  11919. --        dbcc incrementinstance ("SQL Replication QueueReader", "QueueReader:Delivered Trans/sec", @agent_name, @transaction_rate)
  11920.     end
  11921.  
  11922.     --
  11923.     -- Set error id to 0 unless the user want to log errors associate with this 
  11924.     -- history message.
  11925.     --
  11926.     IF (@log_error = 1)
  11927.     begin
  11928.         select @runstatus = @failure
  11929.         EXEC dbo.sp_MSget_new_errorid @error_id OUTPUT
  11930.     end
  11931.     ELSE
  11932.         SELECT @error_id = 0    
  11933.         
  11934.     -- Insert idle record or update if history record is already 'idle'
  11935.     IF (@runstatus = @idle or @update_existing_row = 1)
  11936.     begin
  11937.         -- Attempt to update the last row if it is IDLE
  11938.         UPDATE MSqreader_history 
  11939.         SET     publication_id = @pubid,
  11940.                 runstatus = @runstatus, 
  11941.                 time = @current_time, 
  11942.                 duration = @duration,
  11943.                 comments = @comments,
  11944.                 transaction_id = @transaction_id,
  11945.                 transaction_status = @transaction_status,
  11946.                 transactions_processed = @transactions_processed,
  11947.                 commands_processed = @commands_processed,
  11948.                 delivery_rate = @cmdprocessed_rate,
  11949.                 transaction_rate = @transaction_rate,
  11950.                 subscriber = @subscriber,
  11951.                 subscriberdb = @subscriberdb,
  11952.                 error_id = case @error_id when 0 then error_id else @error_id end
  11953.                 WHERE
  11954.                 agent_id = @agent_id and
  11955.                 timestamp = @lastrow_timestamp and
  11956.                 runstatus = @runstatus
  11957.  
  11958.         -- Insert idle record if there is not one
  11959.         if (@@ROWCOUNT = 0)
  11960.         begin
  11961.             INSERT INTO MSqreader_history(agent_id, publication_id, runstatus, start_time, time, 
  11962.                     duration, comments, transaction_id, transaction_status, 
  11963.                     transactions_processed, commands_processed, delivery_rate, 
  11964.                     transaction_rate, subscriber, subscriberdb, error_id)
  11965.             VALUES(@agent_id, @pubid, @runstatus, @start_time, @current_time, 
  11966.                     @duration, @comments, @transaction_id, @transaction_status,
  11967.                     @transactions_processed, @commands_processed, @cmdprocessed_rate, 
  11968.                     @transaction_rate, @subscriber, @subscriberdb, @error_id)
  11969.         end
  11970.     end
  11971.     else
  11972.     begin
  11973.         INSERT INTO MSqreader_history(agent_id, publication_id, runstatus, start_time, time, 
  11974.                 duration, comments, transaction_id, transaction_status, 
  11975.                 transactions_processed, commands_processed, delivery_rate,
  11976.                 transaction_rate, subscriber, subscriberdb, error_id)
  11977.         VALUES(@agent_id, @pubid, @runstatus, @start_time, @current_time, 
  11978.                 @duration, @comments, @transaction_id, @transaction_status, 
  11979.                 @transactions_processed, @commands_processed, @cmdprocessed_rate, 
  11980.                 @transaction_rate, @subscriber, @subscriberdb, @error_id)
  11981.     end
  11982.  
  11983.     --
  11984.     -- Update global replication agent status table
  11985.     --        
  11986.     exec @retcode = dbo.sp_MSupdate_replication_status 
  11987.         @@servername, 
  11988.         @database,
  11989.         @publication = 'ALL',
  11990.         @agent_type = 9,
  11991.         @agent_name = @agent_name,
  11992.         @status = @runstatus
  11993.     if (@retcode != 0 and @@error != 0)
  11994.         return 1
  11995.  
  11996.     -- Raise the appropriate error
  11997.     if (@do_raiserror = 1)
  11998.     begin
  11999.         select @agentclassname = formatmessage(14581)
  12000.         exec dbo.sp_MSrepl_raiserror @agentclassname, @agent_name, @runstatus, @comments
  12001.     end
  12002.  
  12003.     IF (@@ERROR != 0)
  12004.         RETURN (1)
  12005. END
  12006. GO   
  12007.  
  12008. raiserror(15339,-1,-1,'sp_MSadd_snapshot_history')
  12009. go
  12010. CREATE PROCEDURE sp_MSadd_snapshot_history (
  12011.     @agent_id int,
  12012.     @runstatus int, 
  12013.     @comments nvarchar(255),
  12014.     @delivered_transactions int = 0,    
  12015.     @delivered_commands int = 0,        
  12016.     @log_error bit = 0,
  12017.     @perfmon_increment bit = 1,
  12018.     @update_existing_row bit = 0,
  12019.     @do_raiserror bit = 1,
  12020.     @start_time_string nvarchar(25) = null
  12021. )
  12022. AS
  12023. BEGIN
  12024.  
  12025.     DECLARE @current_time datetime
  12026.             ,@start_time datetime
  12027.             ,@duration int
  12028.             ,@delivery_rate float
  12029.             ,@error_id int
  12030.             ,@retcode int
  12031.             ,@idle int
  12032.             ,@succeed int
  12033.             ,@startup int
  12034.             ,@retry int
  12035.             ,@failure int
  12036.             ,@inprogress int
  12037.             ,@lastrow_timestamp timestamp
  12038.             ,@publisher sysname
  12039.             ,@publisher_db sysname
  12040.             ,@publication sysname
  12041.             ,@agent_name nvarchar(100)
  12042.             ,@perfmon_delivery_rate int
  12043.             ,@agentclassname sysname
  12044.  
  12045.     /* 
  12046.     ** Status const defined in sqlrepl.h 
  12047.     */
  12048.     select @startup = 1
  12049.             ,@succeed = 2
  12050.             ,@inprogress = 3
  12051.             ,@idle = 4
  12052.             ,@retry = 5
  12053.             ,@failure = 6
  12054.             ,@current_time = GETDATE()
  12055.  
  12056.     -- Get named information 
  12057.     select @publisher = srvname, @publisher_db = publisher_db, @publication = publication,
  12058.         @agent_name = name from master..sysservers, MSsnapshot_agents where
  12059.         id = @agent_id and
  12060.         publisher_id = srvid
  12061.  
  12062.     -- Update Perfmon counter
  12063.     if @perfmon_increment = 1
  12064.     begin
  12065.         if @runstatus = @startup
  12066.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Snapshot", 1)
  12067.         else if (@runstatus = @succeed or @runstatus = @retry or @runstatus = @failure)
  12068.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Snapshot", -1)
  12069.     end
  12070.  
  12071.     /* Get start_time for latest agent run */
  12072.     IF @runstatus <> 1  -- Start status
  12073.     BEGIN
  12074.         
  12075.         IF @start_time_string IS NULL OR @start_time_string = N''
  12076.         BEGIN
  12077.             SELECT TOP 1 @start_time = start_time, @lastrow_timestamp = timestamp
  12078.                 FROM MSsnapshot_history (rowlock)
  12079.                 WHERE 
  12080.                 agent_id = @agent_id
  12081.                 ORDER BY timestamp DESC
  12082.         END
  12083.         ELSE
  12084.         BEGIN
  12085.             SELECT @start_time = @start_time_string
  12086.         END
  12087.     END
  12088.     ELSE
  12089.     BEGIN
  12090.         WAITFOR DELAY '000:00:01'
  12091.         SELECT @current_time = DATEADD(ms, CONVERT(INT, 1000.0 * (RAND(@@spid) + RAND() + RAND())/3.0), @current_time)
  12092.         SELECT @start_time = @current_time
  12093.     END
  12094.     /* Calculate agent run duration */
  12095.     SELECT @duration = DATEDIFF(second, @start_time, @current_time) 
  12096.  
  12097.     /* Calculate delivery_rate */
  12098.     IF @duration <> 0 
  12099.        SELECT @delivery_rate = (@delivered_commands * 1.0)/@duration 
  12100.     ELSE
  12101.        SELECT @delivery_rate = 0
  12102.  
  12103.     -- Set Perfmon counters
  12104.     if @runstatus = @idle or @runstatus = @inprogress
  12105.     begin
  12106.         dbcc addinstance ("SQL Replication Snapshot", @agent_name)
  12107.         dbcc incrementinstance ("SQL Replication Snapshot", "Snapshot:Delivered Cmds/sec", @agent_name, @delivered_commands)
  12108.         dbcc incrementinstance ("SQL Replication Snapshot", "Snapshot:Delivered Trans/sec", @agent_name, @delivered_transactions)
  12109.     end
  12110.  
  12111.     /* 
  12112.     ** Set error id to 0 unless the user want to log errors associate with this 
  12113.     ** history message.
  12114.     */
  12115.     SELECT @error_id = 0
  12116.     IF @log_error = 1
  12117.         -- Ignore errors here. @error_id will be set to 0 in case of errors  
  12118.         EXEC dbo.sp_MSget_new_errorid @error_id OUTPUT
  12119.  
  12120.     -- Insert idle record or update if history record is already 'idle'
  12121.     IF @runstatus = @idle or @update_existing_row = 1
  12122.     begin
  12123.         -- Attempt to update the last row if it is IDLE
  12124.         UPDATE MSsnapshot_history SET runstatus = @runstatus, time = @current_time, duration = @duration,
  12125.             comments = @comments,
  12126.             delivered_transactions = @delivered_transactions,
  12127.             delivered_commands = @delivered_commands,
  12128.             delivery_rate = @delivery_rate,
  12129.             error_id = case @error_id when 0 then error_id else @error_id end    
  12130.             WHERE
  12131.             agent_id = @agent_id and
  12132.             timestamp = @lastrow_timestamp and
  12133.             runstatus = @runstatus
  12134.  
  12135.         -- Insert idle record if there is not one
  12136.         if @@ROWCOUNT = 0
  12137.         begin
  12138.             INSERT INTO MSsnapshot_history VALUES (@agent_id, @runstatus, @start_time, 
  12139.             @current_time, @duration, @comments, @delivered_transactions, @delivered_commands, 
  12140.             @delivery_rate, @error_id, NULL)
  12141.         end
  12142.     end
  12143.     else
  12144.     begin
  12145.         INSERT INTO MSsnapshot_history VALUES (@agent_id, @runstatus, @start_time, 
  12146.             @current_time, @duration, @comments, @delivered_transactions, @delivered_commands, 
  12147.             @delivery_rate, @error_id, NULL)
  12148.     end
  12149.  
  12150.     -- Update global replication agent status table
  12151.     exec dbo.sp_MSupdate_replication_status 
  12152.         @publisher, 
  12153.         @publisher_db,
  12154.         @publication,
  12155.         @agent_type = 1,
  12156.         @agent_name = @agent_name,
  12157.         @status = @runstatus
  12158.  
  12159.     -- Raise the appropriate error
  12160.     if @do_raiserror = 1
  12161.     begin
  12162.         select @agentclassname = formatmessage(14551)
  12163.         exec dbo.sp_MSrepl_raiserror @agentclassname, @agent_name, @runstatus, @comments
  12164.     end
  12165.  
  12166.     IF @@ERROR <> 0
  12167.        RETURN (1)
  12168.  
  12169.     if @runstatus = 1
  12170.     begin
  12171.         select 'start_time' = convert(nvarchar(12), @start_time, 112) +
  12172.             substring(convert(nvarchar(24), @start_time, 121), 11, 13)
  12173.     end
  12174. END
  12175. GO   
  12176.  
  12177.  
  12178. raiserror(15339,-1,-1,'sp_MSadd_logreader_history')
  12179. go
  12180. CREATE PROCEDURE sp_MSadd_logreader_history (
  12181.     @agent_id int,
  12182.     @runstatus int,
  12183.     @comments nvarchar(255),
  12184.     @xact_seqno varbinary(16) = NULL,
  12185.     @delivery_time int = 0,                 -- Current delivery time (milliseconds)
  12186.     @delivered_transactions int = 0,        -- Running total of session
  12187.     @delivered_commands int = 0,            -- Running total of session
  12188.     @delivery_latency int = 0,              -- Current latency 
  12189.     @log_error bit = 0,
  12190.     @perfmon_increment bit = 1,
  12191.     @update_existing_row bit = 0,
  12192.     @do_raiserror bit = 1
  12193. )
  12194. AS
  12195. BEGIN
  12196.  
  12197.     DECLARE @current_time datetime
  12198.             ,@start_time datetime
  12199.             ,@duration int
  12200.             ,@average_commands int
  12201.             ,@delivery_rate float
  12202.             ,@error_id int
  12203.             ,@retcode int
  12204.             ,@idle int
  12205.             ,@succeed int
  12206.             ,@startup int
  12207.             ,@retry int
  12208.             ,@inprogress int
  12209.             ,@failure int
  12210.             ,@lastrow_timestamp timestamp
  12211.             ,@publisher sysname
  12212.             ,@publisher_db sysname
  12213.             ,@publication sysname
  12214.             ,@agent_name nvarchar(100)
  12215.             ,@last_delivered_commands int
  12216.             ,@last_delivered_transactions int
  12217.             ,@latest_delivered_commands int
  12218.             ,@latest_delivered_transactions int
  12219.             ,@latest_delivery_rate int
  12220.             ,@last_delivery_rate int             -- int for perfmon
  12221.             ,@last_delivery_latency int
  12222.             ,@last_delivery_time int
  12223.             ,@avg_delivery_rate float
  12224.             ,@avg_delivery_latency int
  12225.             ,@total_delivery_time int
  12226.             ,@agentclassname sysname
  12227.  
  12228.     /* 
  12229.     ** Status const defined in sqlrepl.h 
  12230.     */
  12231.     select @startup = 1
  12232.             ,@succeed = 2
  12233.             ,@inprogress = 3
  12234.             ,@idle = 4
  12235.             ,@retry = 5
  12236.             ,@failure = 6
  12237.             ,@current_time = GETDATE()
  12238.  
  12239.     -- Update Perfmon counter
  12240.     if @perfmon_increment = 1
  12241.     begin
  12242.         if @runstatus = @startup
  12243.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Logreader", 1)
  12244.         else if (@runstatus = @succeed or @runstatus = @retry or @runstatus = @failure)
  12245.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Logreader", -1)
  12246.     end
  12247.  
  12248.     /* Get start_time for latest agent run */
  12249.     IF @runstatus <> 1  -- Startup status
  12250.     BEGIN
  12251.         SELECT TOP 1 @start_time = start_time, 
  12252.             @lastrow_timestamp = timestamp, 
  12253.             @last_delivered_commands = isnull(delivered_commands, 0),
  12254.             @last_delivered_transactions = isnull(delivered_transactions, 0),
  12255.             @last_delivery_latency = isnull(delivery_latency, 0),
  12256.             @last_delivery_time = isnull(delivery_time, 0),
  12257.             @last_delivery_rate = isnull(delivery_rate, 0)
  12258.         FROM MSlogreader_history (rowlock)
  12259.             WHERE agent_id = @agent_id
  12260.                 ORDER BY timestamp DESC
  12261.     END
  12262.     ELSE
  12263.     BEGIN
  12264.         SELECT @start_time = @current_time
  12265.         SET @last_delivered_commands = 0
  12266.         SET @last_delivered_transactions = 0
  12267.         SET @last_delivery_latency = 0
  12268.         SET @last_delivery_time = 0
  12269.         SET @last_delivery_rate = 0
  12270.         SET @last_delivery_latency = 0
  12271.     END
  12272.  
  12273.     /* Use the current time if no corresponding start_up message logged */
  12274.     IF @start_time is NULL
  12275.        SELECT @start_time = @current_time
  12276.  
  12277.     -- Calculate number of transactions in this history
  12278.     set @latest_delivered_commands = @delivered_commands - @last_delivered_commands
  12279.  
  12280.     -- Calculate number of commands in this history
  12281.     set @latest_delivered_transactions = @delivered_transactions - @last_delivered_transactions
  12282.  
  12283.     /* Calculate agent run duration */
  12284.     SELECT @duration = DATEDIFF(second, @start_time, @current_time) 
  12285.  
  12286.     -- Calculate total delivery_time 
  12287.     if @latest_delivered_commands <> 0      -- Work around for Logreader passing in @delivery_time on shutdown.
  12288.         SELECT @total_delivery_time = @delivery_time + @last_delivery_time
  12289.     else
  12290.         SELECT @total_delivery_time = @last_delivery_time
  12291.  
  12292.     -- Calculate average delivery_rate of the session
  12293.     IF @latest_delivered_commands <> 0 and @total_delivery_time <> 0
  12294.     BEGIN
  12295.         SELECT @avg_delivery_rate = (@delivered_commands * 1.0)/(@total_delivery_time/1000.0)
  12296.  
  12297.         -- Current history delivery rate
  12298.         if @delivery_time <> 0
  12299.             SELECT @latest_delivery_rate = (@latest_delivered_commands * 1.0)/(@delivery_time/1000.0)
  12300.         else 
  12301.             SELECT @latest_delivery_rate = 0
  12302.     END
  12303.     ELSE
  12304.     BEGIN
  12305.         SELECT @avg_delivery_rate = @last_delivery_rate
  12306.         SELECT @latest_delivery_rate = 0
  12307.     END
  12308.  
  12309.     -- Calculate the average delivery_latency of the session
  12310.     if @latest_delivered_commands <> 0      -- Work around for Logreader passing in @delivery_latency on shutdown.
  12311.     BEGIN
  12312.         IF @delivery_latency <> 0
  12313.             IF @last_delivery_latency <> 0
  12314.                 SELECT @avg_delivery_latency = (@delivery_latency + @last_delivery_latency)/2
  12315.             ElSE
  12316.                 SELECT @avg_delivery_latency = @delivery_latency
  12317.         ELSE
  12318.             SELECT @avg_delivery_latency = 0
  12319.     END
  12320.     ELSE
  12321.     BEGIN
  12322.         SELECT @avg_delivery_latency = @last_delivery_latency
  12323.  
  12324.         -- Ignore latency value if no commands
  12325.         SELECT @delivery_latency = 0    
  12326.     END
  12327.  
  12328.     /*
  12329.     ** Calculate average number of commands per transaction
  12330.     */
  12331.     IF @delivered_commands <> 0
  12332.        SELECT @average_commands = @delivered_commands/@delivered_transactions
  12333.     ELSE
  12334.  
  12335.        SELECT @average_commands = 0
  12336.  
  12337.     -- Set Perfmon counters
  12338.     select @agent_name = name from MSlogreader_agents where id = @agent_id
  12339.     if @runstatus = @idle or @runstatus = @inprogress
  12340.     begin
  12341.         dbcc addinstance ("SQL Replication Logreader", @agent_name)
  12342.         dbcc incrementinstance ("SQL Replication Logreader", "Logreader:Delivered Trans/sec", @agent_name, @latest_delivered_transactions)
  12343.         dbcc incrementinstance ("SQL Replication Logreader", "Logreader:Delivered Cmds/sec", @agent_name, @latest_delivered_commands)
  12344.         dbcc setinstance ("SQL Replication Logreader", "Logreader:Delivery Latency", @agent_name, @delivery_latency)
  12345.     end
  12346.     else
  12347.     begin
  12348.         dbcc addinstance ("SQL Replication Logreader", @agent_name)
  12349.         dbcc setinstance ("SQL Replication Logreader", "Logreader:Delivery Latency", @agent_name, 0)
  12350.     end
  12351.  
  12352.     /* 
  12353.     ** Set error id to 0 unless the user want to log errors associate with this 
  12354.     ** history message.
  12355.     */
  12356.     SELECT @error_id = 0
  12357.     IF @log_error = 1
  12358.         -- Ignore errors here. @error_id will be set to 0 in case of errors  
  12359.         EXEC dbo.sp_MSget_new_errorid @error_id OUTPUT
  12360.  
  12361.     -- Insert idle record or update if history record is already 'idle'
  12362.     IF @runstatus = @idle or @update_existing_row = 1
  12363.     begin
  12364.         -- Attempt to update the last row if it is IDLE
  12365.         if (@runstatus = @idle)
  12366.         begin
  12367.             UPDATE MSlogreader_history SET runstatus = @runstatus, time = @current_time,
  12368.             duration = @duration,comments = @comments,
  12369.             error_id = case @error_id when 0 then error_id else @error_id end
  12370.             WHERE
  12371.             agent_id = @agent_id and
  12372.             timestamp = @lastrow_timestamp and
  12373.             ( runstatus = @runstatus or 
  12374.             (@update_existing_row = 1 and runstatus in (@idle, @inprogress) and @runstatus in (@idle, @inprogress)) )
  12375.         end
  12376.         else
  12377.         begin
  12378.             UPDATE MSlogreader_history SET runstatus = @runstatus, start_time = @start_time, 
  12379.             time = @current_time,
  12380.             duration = @duration, comments = @comments,
  12381.             xact_seqno = @xact_seqno,
  12382.             delivery_time = @total_delivery_time,
  12383.             delivered_transactions = @delivered_transactions,
  12384.             delivered_commands = @delivered_commands,
  12385.             average_commands = @average_commands,
  12386.             delivery_rate = @avg_delivery_rate,
  12387.             delivery_latency = @avg_delivery_latency,
  12388.             error_id = case @error_id when 0 then error_id else @error_id end
  12389.             WHERE
  12390.             agent_id = @agent_id and
  12391.             timestamp = @lastrow_timestamp and
  12392.             ( runstatus = @runstatus or 
  12393.             (@update_existing_row = 1 and runstatus in (@idle, @inprogress) and @runstatus in (@idle, @inprogress)) )
  12394.         end
  12395.  
  12396.         -- Insert idle record if there is not one
  12397.         if @@ROWCOUNT = 0
  12398.         begin
  12399.             -- Use last values because nothing was done
  12400.             INSERT INTO MSlogreader_history VALUES (@agent_id, @runstatus, @start_time, @current_time, 
  12401.                 @duration, @comments,  
  12402.                 @xact_seqno, @last_delivery_time, @delivered_transactions, @delivered_commands,
  12403.                 @average_commands, @avg_delivery_rate, @last_delivery_latency, @error_id, NULL)
  12404.         end
  12405.     end
  12406.     else
  12407.     begin
  12408.         INSERT INTO MSlogreader_history VALUES (@agent_id, @runstatus, @start_time, @current_time, 
  12409.             @duration, @comments, 
  12410.             @xact_seqno, @total_delivery_time, @delivered_transactions, @delivered_commands,
  12411.             @average_commands, @avg_delivery_rate, @avg_delivery_latency, @error_id, NULL)
  12412.     end
  12413.  
  12414.     -- Get named information 
  12415.     select @publisher = srvname, @publisher_db = publisher_db, @publication = publication,
  12416.         @agent_name = name from master..sysservers, MSlogreader_agents where
  12417.         id = @agent_id and
  12418.         publisher_id = srvid
  12419.  
  12420.     -- Update global replication agent status table
  12421.     exec dbo.sp_MSupdate_replication_status 
  12422.         @publisher, 
  12423.         @publisher_db,
  12424.         @publication = 'ALL',
  12425.         @agent_type = 2,
  12426.         @agent_name = @agent_name,
  12427.         @status = @runstatus
  12428.  
  12429.     -- Raise the appropriate error
  12430.     if @do_raiserror = 1
  12431.     begin
  12432.         select @agentclassname = formatmessage(14552)
  12433.         exec dbo.sp_MSrepl_raiserror @agentclassname, @agent_name, @runstatus, @comments
  12434.     end
  12435.  
  12436.     IF @@ERROR <> 0
  12437.     BEGIN
  12438.        RETURN (1)
  12439.     END
  12440. END
  12441. GO      
  12442.  
  12443. raiserror(15339,-1,-1,'sp_MSadd_distribution_history')
  12444. go
  12445. CREATE PROCEDURE sp_MSadd_distribution_history (
  12446.     @agent_id int,
  12447.     @runstatus int, 
  12448.     @comments nvarchar(255),
  12449.     @xact_seqno binary(16) = 0x00,      -- We use binary(16)to pad it out for the below compare
  12450.     @delivered_transactions int = 0,        -- Running total for the session
  12451.     @delivered_commands int = 0,            -- Running total for the session
  12452.     @delivery_rate float = 0,               -- Last rate (cmds/sec)
  12453.     @log_error bit = 0,
  12454.     @perfmon_increment bit = 1,
  12455.     @xactseq varbinary(16) = NULL,      
  12456.     @command_id int = NULL,
  12457.     @update_existing_row bit = 0,
  12458.     @updateable_row bit = 1,        -- used to override history verbose level to decide
  12459.                                     -- whether the row being added can be updated by another.    
  12460.     @do_raiserror bit = 1
  12461. )
  12462. AS
  12463. BEGIN
  12464.  
  12465.     set nocount on
  12466.  
  12467.     DECLARE @current_time datetime
  12468.             ,@start_time datetime
  12469.             ,@entry_time datetime
  12470.             ,@duration int                   -- milliseconds
  12471.             ,@delivery_latency int
  12472.             ,@average_commands int
  12473.             ,@total_cmds int
  12474.             ,@publisher_id smallint
  12475.             ,@publisher_db sysname
  12476.             ,@publication sysname
  12477.             ,@publisher sysname
  12478.             ,@subscriber_id smallint
  12479.             ,@subscriber sysname
  12480.             ,@subscriber_db sysname
  12481.             ,@article sysname
  12482.             ,@article_id int
  12483.             ,@publication_id int
  12484.             ,@publisher_database_id int
  12485.  
  12486.             ,@agent_name nvarchar(100)
  12487.             ,@error_id int 
  12488.             ,@startup int
  12489.             ,@succeed int
  12490.             ,@inprogress int
  12491.             ,@retry int
  12492.             ,@failure int
  12493.             ,@validation_failure int
  12494.             ,@validation_success int, @error_skipped int
  12495.             ,@requested_shutdown int
  12496.             ,@raiserror_status int
  12497.             ,@idle int
  12498.             ,@lastrow_timestamp timestamp
  12499.             ,@lastrow_xact_seqno binary(16)
  12500.             ,@new_delivered_commands int
  12501.             ,@new_delivered_transactions int
  12502.             ,@retcode int
  12503.             ,@last_delivery_rate float
  12504.             ,@last_delivery_latency int
  12505.             ,@avg_delivery_rate float
  12506.             ,@avg_delivery_latency int
  12507.             ,@perfmon_delivery_rate int
  12508.             ,@existing_row_updateble bit
  12509.             ,@this_row_updateable bit
  12510.             ,@agentclassname sysname
  12511.             ,@MAXINT int
  12512.  
  12513.     /* 
  12514.     ** Status const defined in sqlrepl.h 
  12515.     */
  12516.     select @startup = 1
  12517.             ,@succeed = 2
  12518.             ,@inprogress = 3
  12519.             ,@idle = 4
  12520.             ,@retry = 5
  12521.             ,@failure = 6
  12522.             ,@validation_failure = 7
  12523.             ,@validation_success = 8
  12524.             ,@requested_shutdown = 9
  12525.             ,@error_skipped = 10
  12526.             ,@MAXINT = 2147483647
  12527.  
  12528.     -- To prevent cleanup up being messed up by invalid history message, only log
  12529.     -- valid history message. 
  12530.     if @runstatus > 10 or @runstatus < 1
  12531.     begin
  12532.         --Invalid history message logged
  12533.         RAISERROR (21079, 16, -1, @runstatus)
  12534.         return (1)
  12535.     end
  12536.  
  12537.     select @existing_row_updateble = 1
  12538.     select @this_row_updateable = 1
  12539.  
  12540.     select @raiserror_status = @runstatus
  12541.     if (@runstatus = @validation_failure or @runstatus = @validation_success 
  12542.         or @runstatus = @requested_shutdown or @runstatus = @error_skipped)
  12543.     begin
  12544.         select @runstatus = @inprogress
  12545.         select @this_row_updateable = 0
  12546.     end
  12547.  
  12548.     if (@updateable_row = 0)
  12549.     begin
  12550.         select @this_row_updateable = 0
  12551.     end
  12552.     
  12553.     -- Security Check
  12554.     exec @retcode = dbo.sp_MScheck_pull_access
  12555.         @agent_id = @agent_id,
  12556.         @agent_type = 0 -- distribution agent
  12557.     if @@error <> 0 or @retcode <> 0
  12558.         return (1)
  12559.  
  12560.     SELECT @current_time = GETDATE()
  12561.  
  12562.     -- Update Perfmon counter
  12563.     if @perfmon_increment = 1
  12564.     begin
  12565.         if @runstatus = @startup
  12566.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Distribution", 1)
  12567.         else if (@runstatus = @succeed or @runstatus = @retry or @runstatus = @failure)
  12568.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Distribution", -1)
  12569.     end
  12570.  
  12571.     -- Get agent name, publisher id and publisher_db
  12572.     select @agent_name = name, 
  12573.         @publisher_database_id = publisher_database_id,
  12574.         @publisher_id = publisher_id, @publisher_db = publisher_db,
  12575.         @publication =  publication, @subscriber_id = subscriber_id, @subscriber_db = subscriber_db
  12576.         from MSdistribution_agents
  12577.         where id = @agent_id
  12578.     select @publisher = srvname from master..sysservers where srvid = @publisher_id
  12579.     select @subscriber = srvname from master..sysservers where srvid = @subscriber_id
  12580.  
  12581.     /* Get start_time and xact_seqno for latest agent run */
  12582.     IF @runstatus <> 1   
  12583.     BEGIN
  12584.           
  12585.         SELECT TOP 1 
  12586.             @lastrow_xact_seqno = xact_seqno,
  12587.             @start_time = start_time, 
  12588.             @total_cmds = total_delivered_commands,
  12589.             @lastrow_timestamp = timestamp, 
  12590.             @new_delivered_transactions = @delivered_transactions - delivered_transactions,
  12591.             @new_delivered_commands = @delivered_commands - delivered_commands,
  12592.             @last_delivery_rate = delivery_rate,
  12593.             @last_delivery_latency = delivery_latency,
  12594.             @existing_row_updateble = updateable_row
  12595.         FROM MSdistribution_history (rowlock)
  12596.             WHERE agent_id = @agent_id 
  12597.             ORDER BY timestamp  DESC
  12598.  
  12599.         /* 
  12600.         ** Check the case where the user did not pass in the proper values
  12601.         ** for delivered commands and transactions (this leads to negative
  12602.         ** new command/tran counts).
  12603.         */
  12604.         if ( @new_delivered_commands < 0)
  12605.             SELECT @new_delivered_commands = 0
  12606.  
  12607.         if ( @new_delivered_transactions < 0 )
  12608.             SELECT @new_delivered_transactions = 0
  12609.  
  12610.     END
  12611.     ELSE
  12612.     BEGIN
  12613.         -- At least get running total of commands over all sessions.
  12614.         SELECT TOP 1 
  12615.             @lastrow_xact_seqno = xact_seqno,
  12616.             @total_cmds = total_delivered_commands
  12617.             FROM MSdistribution_history  (rowlock)
  12618.             WHERE agent_id = @agent_id
  12619.             ORDER BY timestamp  DESC
  12620.         SELECT @start_time = @current_time
  12621.         SELECT @new_delivered_commands = @delivered_commands
  12622.         SELECT @new_delivered_transactions = @delivered_transactions
  12623.         SELECT @last_delivery_rate = 0
  12624.         SELECT @last_delivery_latency = 0
  12625.     END
  12626.  
  12627.     IF @total_cmds IS NULL
  12628.         SELECT @total_cmds = 0
  12629.  
  12630.     /* Use the current time if no corresponding start_up message logged */
  12631.     IF @start_time is NULL
  12632.        SELECT @start_time = @current_time
  12633.  
  12634.     /* Calculate agent run duration */
  12635.     SELECT @duration = DATEDIFF(second, @start_time, @current_time) 
  12636.     
  12637.     IF @delivered_commands <> 0
  12638.        SELECT @average_commands = @delivered_commands/@delivered_transactions
  12639.     ELSE
  12640.        SELECT @average_commands = 0
  12641.  
  12642.     -- Get the entry time of the last distributed transaction
  12643.     if @xact_seqno <> 0x00 and @new_delivered_commands <> 0
  12644.         -- SELECT @entry_time = entry_time FROM MSrepl_transactions (READPAST)
  12645.         SELECT @entry_time = entry_time FROM MSrepl_transactions 
  12646.            WHERE xact_seqno = @xact_seqno and
  12647.                 publisher_database_id = @publisher_database_id
  12648.  
  12649.     -- Calculate the latency of the last distributed transaction
  12650.     IF @entry_time IS NOT NULL
  12651.     begin
  12652.        -- Calculte diff in minutes.
  12653.        declare @diff_min int
  12654.        select @diff_min = DATEDIFF(minute, @entry_time, @current_time)
  12655.        if @diff_min > 16666
  12656.             select @delivery_latency = 999999999
  12657.        else 
  12658.             select @delivery_latency = DATEDIFF(millisecond, @entry_time, @current_time)
  12659.     end
  12660.     ELSE
  12661.        SELECT @delivery_latency = 0
  12662.  
  12663.     -- Calculate the average delivery latency of the session
  12664.     IF @last_delivery_latency = 0
  12665.         SET @avg_delivery_latency = @delivery_latency
  12666.     ELSE IF @delivery_latency = 0
  12667.         SET @avg_delivery_latency = @last_delivery_latency
  12668.     ELSE
  12669.         SET @avg_delivery_latency = (@delivery_latency + @last_delivery_latency)/2
  12670.  
  12671.     -- Calculate average delivery rate of the session
  12672.  
  12673.     IF @last_delivery_rate = 0
  12674.         SET @avg_delivery_rate = @delivery_rate
  12675.     ELSE IF @delivery_rate = 0 or @new_delivered_commands = 0
  12676.         SET @avg_delivery_rate = @last_delivery_rate
  12677.     ELSE
  12678.         SET @avg_delivery_rate = (@delivery_rate + @last_delivery_rate)/2.0     
  12679.  
  12680.     /* Calculate grand total of delivered trans across sessions, check
  12681.     ** to make sure the result does not overflow integer column  
  12682.     */
  12683.     if (@total_cmds > @MAXINT  - @new_delivered_commands)
  12684.         SET @total_cmds = @MAXINT
  12685.     else
  12686.         SET @total_cmds = @total_cmds + @new_delivered_commands
  12687.  
  12688.     -- Set Perfmon counters
  12689.     if @runstatus = @idle or @runstatus = @inprogress
  12690.     begin
  12691.         dbcc addinstance ("SQL Replication Distribution", @agent_name)
  12692.         dbcc incrementinstance ("SQL Replication Distribution", "Dist:Delivered Trans/sec", @agent_name, @new_delivered_transactions)
  12693.         dbcc incrementinstance ("SQL Replication Distribution", "Dist:Delivered Cmds/sec", @agent_name, @new_delivered_commands)
  12694.         dbcc setinstance ("SQL Replication Distribution", "Dist:Delivery Latency", @agent_name, @delivery_latency)
  12695.     end
  12696.     else
  12697.     begin /* Reset latency counter */
  12698.         dbcc addinstance ("SQL Replication Distribution", @agent_name)
  12699.         dbcc setinstance ("SQL Replication Distribution", "Dist:Delivery Latency", @agent_name, 0)
  12700.     end
  12701.  
  12702.     /* 
  12703.     ** Set error id to 0 unless the user want to log errors associate with this 
  12704.     ** history message.
  12705.     */
  12706.     SELECT @error_id = 0
  12707.     IF @log_error = 1
  12708.         -- Ignore errors here. @error_id will be set to 0 in case of errors  
  12709.         EXEC dbo.sp_MSget_new_errorid @error_id OUTPUT, @xactseq, @command_id
  12710.     
  12711.     -- @xact_seqno may be uninitialized for the first several messages after
  12712.     -- the start-up of the distribtion agent. Get the correct value in that case. 
  12713.     -- We must do this because distribution cleanup will use the lastest xact_seqno
  12714.     -- as cleanup boundary.
  12715.     -- Note: @last_xact_seqno might be NULL
  12716.     -- Only do this if @xact_seqno is 0, since a smaller xact_seqno might be logged due
  12717.     -- to reinited sub for immediate_sync pub.
  12718.     -- This will prevent history being messed up by one gabage history entry.
  12719.     if @xact_seqno = 0x00 and @lastrow_xact_seqno is not null
  12720.         select @xact_seqno = @lastrow_xact_seqno 
  12721.  
  12722.     -- Insert idle record or update if history record is already 'idle'
  12723.     IF (@existing_row_updateble = 1) and (@runstatus = @idle or @update_existing_row = 1)
  12724.     begin
  12725.  
  12726.         -- Attempt to update the last row if it is IDLE
  12727.         if (@runstatus = @idle)
  12728.         begin
  12729.             UPDATE MSdistribution_history SET runstatus = @runstatus, time = @current_time,
  12730.             duration = @duration, comments = @comments,
  12731.             xact_seqno = @xact_seqno, updateable_row = @this_row_updateable,
  12732.             error_id = case @error_id when 0 then error_id else @error_id end
  12733.             WHERE
  12734.             agent_id = @agent_id and
  12735.             timestamp = @lastrow_timestamp and
  12736.             ( runstatus = @runstatus or 
  12737.             (@update_existing_row = 1 and runstatus in (@idle, @inprogress) and @runstatus in (@idle, @inprogress)) )
  12738.         end
  12739.         else
  12740.         begin
  12741.             -- Attempt to update the last row if it is IDLE
  12742.             UPDATE MSdistribution_history SET runstatus = @runstatus, start_time = @start_time,
  12743.                 time = @current_time,
  12744.                 duration = @duration,
  12745.                 xact_seqno = @xact_seqno,
  12746.                 comments = @comments,
  12747.                 delivered_transactions = @delivered_transactions,
  12748.                 delivered_commands = @delivered_commands,
  12749.                 average_commands = @average_commands,
  12750.                 delivery_rate = @avg_delivery_rate,
  12751.                 delivery_latency = @avg_delivery_latency,
  12752.                 total_delivered_commands = @total_cmds,
  12753.                 current_delivery_rate = @delivery_rate,
  12754.                 current_delivery_latency = @delivery_latency,
  12755.                 updateable_row = @this_row_updateable,
  12756.                 error_id = case @error_id when 0 then error_id else @error_id end
  12757.                 WHERE
  12758.                 agent_id = @agent_id and
  12759.                 timestamp = @lastrow_timestamp and
  12760.                 ( runstatus = @runstatus or 
  12761.                 (@update_existing_row = 1 and runstatus in (@idle, @inprogress) and @runstatus in (@idle, @inprogress)) )
  12762.         end
  12763.     
  12764.         -- Insert idle record if there is not one
  12765.         if @@ROWCOUNT = 0
  12766.         begin
  12767.             INSERT INTO MSdistribution_history (agent_id, runstatus, start_time, time, duration, comments, xact_seqno,
  12768.                 delivered_transactions, delivered_commands, average_commands, delivery_rate, delivery_latency,
  12769.                 total_delivered_commands, error_id, timestamp, current_delivery_rate, current_delivery_latency, updateable_row)
  12770.             VALUES (@agent_id, @runstatus, @start_time, @current_time, 
  12771.                 @duration, @comments, @xact_seqno, @delivered_transactions, 
  12772.                 @delivered_commands, @average_commands, @avg_delivery_rate,
  12773.                 @avg_delivery_latency, @total_cmds, @error_id, NULL, @delivery_rate, @delivery_latency, @this_row_updateable)
  12774.         end
  12775.     end
  12776.     else
  12777.     begin
  12778.         INSERT INTO MSdistribution_history (agent_id, runstatus, start_time, time, duration, comments, xact_seqno,
  12779.                 delivered_transactions, delivered_commands, average_commands, delivery_rate, delivery_latency,
  12780.                 total_delivered_commands, error_id, timestamp, current_delivery_rate, current_delivery_latency, updateable_row)
  12781.         VALUES (@agent_id, @runstatus, @start_time, @current_time, 
  12782.             @duration, @comments, @xact_seqno, @delivered_transactions, 
  12783.             @delivered_commands, @average_commands, @avg_delivery_rate,
  12784.             @avg_delivery_latency, @total_cmds, @error_id, NULL, @delivery_rate, @delivery_latency, @this_row_updateable)
  12785.     end
  12786.  
  12787.     -- Refresh repl monitor
  12788.     declare @agent_type int
  12789.     set @agent_type = dbo.fn_MSmask_agent_type (@agent_id, 3)
  12790.  
  12791.     -- Update global replication agent status table
  12792.     exec dbo.sp_MSupdate_replication_status 
  12793.         @publisher, 
  12794.         @publisher_db,
  12795.         @publication,
  12796.         @agent_type = @agent_type,
  12797.         @agent_name = @agent_name,
  12798.         @status = @runstatus
  12799.  
  12800.     if (@raiserror_status = @validation_failure or @raiserror_status = @validation_success or
  12801.         @raiserror_status = @error_skipped)
  12802.     begin
  12803.         -- Get the "real" publication name (as opposed to 'ALL') and article name
  12804.         select @article_id = article_id from MSrepl_commands
  12805.         where publisher_database_id = @publisher_database_id
  12806.         and xact_seqno = @xactseq
  12807.         and command_id = @command_id
  12808.     
  12809.         select @publication = mp.publication, @publication_id = mp.publication_id
  12810.         from MSpublications as mp, MSsubscriptions as ms
  12811.         where mp.publisher_id = ms.publisher_id
  12812.         and mp.publisher_db = ms.publisher_db
  12813.         and mp.publication_id = ms.publication_id
  12814.         and ms.publisher_id = @publisher_id
  12815.         and ms.publisher_db = @publisher_db
  12816.         and ms.subscriber_id = @subscriber_id
  12817.         and ms.subscriber_db = @subscriber_db
  12818.         and ms.article_id = @article_id
  12819.  
  12820.         select @article = article
  12821.         from MSarticles
  12822.         where article_id = @article_id
  12823.         and publisher_id = @publisher_id
  12824.         and publisher_db = @publisher_db
  12825.         and publication_id = @publication_id
  12826.     end
  12827.  
  12828.     -- Raise the appropriate error
  12829.     if @do_raiserror = 1
  12830.     begin
  12831.         select @agentclassname = formatmessage(14553)
  12832.         exec dbo.sp_MSrepl_raiserror @agentclassname, @agent_name, @raiserror_status, @comments, @subscriber=@subscriber, @publication=@publication, @article=@article
  12833.     end
  12834.     
  12835.     IF @@ERROR <> 0
  12836.        RETURN (1)
  12837. END
  12838. GO   
  12839.  
  12840. raiserror(15339,-1,-1,'sp_MSsubscription_cleanup')
  12841. GO
  12842. CREATE PROCEDURE sp_MSsubscription_cleanup
  12843.     @cutoff_time datetime
  12844.     as
  12845.  
  12846.     declare @max_time datetime
  12847.     declare @active tinyint
  12848.     declare @inactive tinyint
  12849.     declare @subscribed tinyint
  12850.     declare @virtual_anonymous smallint
  12851.     declare @virtual smallint
  12852.     declare @agent_id int
  12853.     declare @retcode int,
  12854.         @num_dropped int
  12855.  
  12856.     set nocount on
  12857.  
  12858.     select @active = 2
  12859.     select @inactive = 0
  12860.     select @subscribed = 1
  12861.     select @virtual = -1
  12862.     select @virtual_anonymous = -2
  12863.  
  12864.     select @max_time = dateadd(hour, 1, getdate())
  12865.  
  12866.     -- Refer to sp_MSmaximun_cleanup_xact_seqno to understand the logic
  12867.     -- in this sp. If you change the logic here, you may need to change
  12868.     -- that sp as well.
  12869.  
  12870.     -- Deactivate real subscriptions for agents that are working on 
  12871.     -- transactions that are older than @retention
  12872.     -- update all the subscriptions for those agents, including
  12873.     -- subscriptions that are in subscribed state!
  12874.     update MSsubscriptions  set status = @inactive where
  12875.         agent_id in (
  12876.         select a.id from 
  12877.             (select s.agent_id, s.subscription_seqno, max(isnull(h.timestamp,0x00))
  12878.                 from 
  12879.                 -- s stores the agent id and min subscription_seqno for
  12880.                 -- active well known subscriptions
  12881.                 (select s2.agent_id, min(s2.subscription_seqno) from
  12882.                     MSsubscriptions s2 
  12883.                     where
  12884.                     s2.status = @active and
  12885.                     -- Only well-known agent
  12886.                     s2.subscriber_id >= 0
  12887.                     group by s2.agent_id)
  12888.                 s (agent_id, subscription_seqno)
  12889.                 left join MSdistribution_history h
  12890.                 on (h.agent_id = s.agent_id)
  12891.                 group by s.agent_id, s.subscription_seqno)
  12892.             sh (agent_id, subscription_seqno, timestamp)
  12893.             left join MSdistribution_history dh 
  12894.             on (dh.agent_id = sh.agent_id and dh.timestamp = sh.timestamp)
  12895.             -- a is for publisher_database_id
  12896.             join MSdistribution_agents a
  12897.             on (a.id = sh.agent_id)
  12898.             where
  12899.             @cutoff_time > = (
  12900.                 -- Get the entry_time of the first tran that cannot be
  12901.                 -- cleaned up normally because of this agent.
  12902.                 -- Use history if it's larger and it is not null (exists)
  12903.                 case  when dh.xact_seqno >= sh.subscription_seqno 
  12904.                 then
  12905.                     -- Have to join with commands table because transactions that
  12906.                     -- does not have commands will not be picked up by
  12907.                     -- sp_MSget_repl_commands
  12908.                     isnull((select top 1 entry_time from MSrepl_transactions t,
  12909.                         MSrepl_commands c where
  12910.                         t.publisher_database_id = a.publisher_database_id and
  12911.                         c.publisher_database_id = a.publisher_database_id and
  12912.                         c.xact_seqno = t.xact_seqno and
  12913.                         -- history xact_seqno can be cleaned up
  12914.                         t.xact_seqno > isnull(dh.xact_seqno,0x0) and
  12915.                         c.xact_seqno > isnull(dh.xact_seqno,0x0)
  12916.                         order by t.xact_seqno asc), @max_time)
  12917.                 else
  12918.                     isnull((select top 1 entry_time from MSrepl_transactions t,
  12919.                         MSrepl_commands c where
  12920.                         t.publisher_database_id = a.publisher_database_id and
  12921.                         c.publisher_database_id = a.publisher_database_id and
  12922.                         c.xact_seqno = t.xact_seqno and
  12923.                         -- sub xact_seqno cannot be cleaned up
  12924.                         t.xact_seqno >= sh.subscription_seqno and
  12925.                         c.xact_seqno >= sh.subscription_seqno                
  12926.                         order by t.xact_seqno asc), @max_time)
  12927.                 end))
  12928.  
  12929.     if @@rowcount <> 0
  12930.         RAISERROR(21011, 10, -1) 
  12931.  
  12932.     -- Dropping all the aonymous agents that are working on
  12933.     -- transactions that are older than @retention
  12934.     -- No message raised.
  12935.     -- Don't drop agents that do not have history (true for new agents).
  12936.     -- For each publisher/publisherdb pair do cleanup
  12937.     declare hC CURSOR LOCAL FAST_FORWARD FOR 
  12938.         select distinct a.id from 
  12939.             (select s.agent_id, s.subscription_seqno, max(isnull(h.timestamp,0x00))
  12940.                 from 
  12941.                 -- s stores the agent id and min subscription_seqno of newest
  12942.                 -- snapshot for
  12943.                 -- active anonymous subscriptions
  12944.                 (select a2.id, min(s2.subscription_seqno) from
  12945.                     MSsubscriptions s2 
  12946.                     join MSdistribution_agents a2
  12947.                     on (a2.virtual_agent_id = s2.agent_id)
  12948.                     where
  12949.                     s2.status = @active 
  12950.                     group by a2.id)
  12951.                 s (agent_id, subscription_seqno)
  12952.                 join MSdistribution_history h
  12953.                 on (h.agent_id = s.agent_id)
  12954.                 group by s.agent_id, s.subscription_seqno)
  12955.             sh (agent_id, subscription_seqno, timestamp)
  12956.             join MSdistribution_history dh 
  12957.             on (dh.agent_id = sh.agent_id and dh.timestamp = sh.timestamp)
  12958.             join MSdistribution_agents a
  12959.             -- a is for publisher_database_id
  12960.             on (a.id = sh.agent_id)
  12961.             where
  12962.             @cutoff_time > = (
  12963.                 -- Get the entry_time of the first tran that cannot be
  12964.                 -- cleaned up normally because of this agent.
  12965.                 -- Use history if it's larger and it is not null (exists)
  12966.                 case  when dh.xact_seqno > 0x00
  12967.                 then
  12968.                     -- does not have commands will not be picked up by
  12969.                     -- sp_MSget_repl_commands
  12970.                     isnull((select top 1 entry_time from MSrepl_transactions t,
  12971.                         MSrepl_commands c where
  12972.                         t.publisher_database_id = a.publisher_database_id and
  12973.                         c.publisher_database_id = a.publisher_database_id and
  12974.                         c.xact_seqno = t.xact_seqno and
  12975.                         -- history xact_seqno can be cleaned up
  12976.                         t.xact_seqno > isnull(dh.xact_seqno,0x0) and
  12977.                         c.xact_seqno > isnull(dh.xact_seqno,0x0)
  12978.                         order by t.xact_seqno asc), @max_time)
  12979.                 else
  12980.                     isnull((select top 1 entry_time from MSrepl_transactions t,
  12981.                         MSrepl_commands c where
  12982.                         t.publisher_database_id = a.publisher_database_id and
  12983.                         c.publisher_database_id = a.publisher_database_id and
  12984.                         c.xact_seqno = t.xact_seqno and
  12985.                         -- sub xact_seqno cannot be cleaned up
  12986.                         t.xact_seqno >= sh.subscription_seqno and
  12987.                         c.xact_seqno >= sh.subscription_seqno
  12988.                         order by t.xact_seqno asc), @max_time)
  12989.                   end)
  12990.     for read only
  12991.     select @num_dropped = 0
  12992.     open hC
  12993.     fetch hC into @agent_id
  12994.     while (@@fetch_status <> -1)
  12995.     begin
  12996.         exec @retcode = dbo.sp_MSdrop_distribution_agentid @agent_id
  12997.         if @retcode <> 0 or @@error <> 0
  12998.             return (1)
  12999.         select @num_dropped = @num_dropped + 1
  13000.         fetch hC into @agent_id
  13001.     end
  13002.     if @num_dropped > 0
  13003.         RAISERROR(20597, 10, -1, @num_dropped) 
  13004.  
  13005.     -- Deactivating subscriptions virtual subscriptions that are older then @retention.
  13006.     update MSsubscriptions  set status = @subscribed
  13007.         where
  13008.         -- Only change active subscriptions!
  13009.         status = @active and 
  13010.         subscriber_id = @virtual and
  13011.                 -- Get the entry_time of the first tran that cannot be
  13012.                 -- cleaned up normally because of this subscription.
  13013.             isnull((select top 1 entry_time from MSrepl_transactions t where
  13014.                 t.publisher_database_id = MSsubscriptions.publisher_database_id and
  13015.                 xact_seqno >= MSsubscriptions.subscription_seqno
  13016.                 order by t.xact_seqno asc), @max_time)
  13017.             <= @cutoff_time
  13018.     if @@rowcount <> 0
  13019.         RAISERROR(21077, 10, -1) 
  13020. GO
  13021.  
  13022. raiserror(15339,-1,-1,'sp_MSreplremoveuncdir')
  13023. GO
  13024. CREATE PROCEDURE sp_MSreplremoveuncdir
  13025. @dir nvarchar(260)
  13026. as
  13027.  
  13028.     set nocount on
  13029.  
  13030.     declare @retcode int
  13031.     declare @local_dir nvarchar(260)
  13032.     declare @cmd nvarchar(1000)
  13033.     declare @machinename sysname
  13034.     /* 
  13035.     ** We have to convert UNC to drive, otherwise will get 'Access denied' error in xp_cmdshell
  13036.     */
  13037.     select @machinename = convert(sysname, SERVERPROPERTY('machinename'))
  13038.     EXEC @retcode = master.dbo.sp_MSunc_to_drive @unc_path = @dir, 
  13039.         @local_server = @machinename, @local_path = @local_dir OUTPUT
  13040.     IF @retcode <> 0 or @@ERROR <> 0 
  13041.         RETURN(1)
  13042.  
  13043.     /*
  13044.     ** Delete directory in the distributor's directory.
  13045.     ** On Win9x, we have to use deltree instead
  13046.     */
  13047.     declare @platform_nt int 
  13048.     select @platform_nt = 0x1
  13049.     IF (( platform() & @platform_nt = @platform_nt))
  13050.     BEGIN 
  13051.         SELECT @cmd = 'if exist "' + fn_escapecmdshellsymbolsremovequotes(@local_dir) collate database_default + '" rmdir /S /Q ' + '"' + fn_escapecmdshellsymbolsremovequotes(@local_dir) collate database_default + '"'
  13052.     END
  13053.     ELSE
  13054.     BEGIN
  13055.         -- Don't need if exists check on Win9x but we do need 
  13056.         -- to remove the trailing slash
  13057.         IF SUBSTRING(@local_dir, LEN(@local_dir), 1) = N'\'
  13058.         BEGIN
  13059.             SELECT @local_dir = LEFT(@local_dir, LEN(@local_dir)-1)
  13060.         END
  13061.         SELECT @cmd = 'deltree /Y ' + '"' + fn_escapecmdshellsymbolsremovequotes(@local_dir) collate database_default + '"'
  13062.     END
  13063.  
  13064.     EXECUTE  @retcode = master..xp_cmdshell @cmd, NO_OUTPUT
  13065.     IF @retcode <> 0 or @@ERROR <> 0 
  13066.     begin
  13067.         raiserror(20015, 16, -1, @dir)
  13068.         RETURN(1)
  13069.     end
  13070. go
  13071.  
  13072. raiserror(15339,-1,-1,'sp_MSdrop_snapshot_dirs')
  13073. GO
  13074. CREATE PROCEDURE sp_MSdrop_snapshot_dirs
  13075. as
  13076.     declare @retcode int
  13077.     declare @snapshot_bit int
  13078.     declare @directory_type int
  13079.     declare @alt_directory_type int
  13080.     declare @publisher_database_id int
  13081.         
  13082.     declare @dir nvarchar(512)
  13083.     declare @command_id int
  13084.     declare @xact_seqno varbinary(16)
  13085.     
  13086.     select @snapshot_bit = 0x80000000
  13087.     select @directory_type = 7
  13088.     select @alt_directory_type = 25
  13089.  
  13090.     declare  hCdirs  CURSOR LOCAL FAST_FORWARD FOR select CONVERT(nvarchar(512), command),
  13091.         xact_seqno, command_id, publisher_database_id
  13092.         from MSrepl_commands where
  13093.         ((type & ~@snapshot_bit) = @directory_type) or
  13094.         ((type & ~@snapshot_bit) = @alt_directory_type)
  13095.     for read only
  13096.  
  13097.     open hCdirs
  13098.     fetch hCdirs into @dir, @xact_seqno, @command_id, @publisher_database_id
  13099.     while (@@fetch_status <> -1)
  13100.     begin
  13101.          -- Need to map unc to local drive for access problem
  13102.         exec @retcode = dbo.sp_MSreplremoveuncdir @dir
  13103.         /* Abort the operation if the delete fails */
  13104.         if (@retcode <> 0 or @@error <> 0)
  13105.             return (1)
  13106.  
  13107.         delete MSrepl_commands where 
  13108.             publisher_database_id = @publisher_database_id and
  13109.             xact_seqno = @xact_seqno and
  13110.             command_id = @command_id
  13111.  
  13112.         fetch hCdirs into @dir, @xact_seqno, @command_id, @publisher_database_id
  13113.     end
  13114.     close hCdirs
  13115.     deallocate hCdirs
  13116. GO
  13117.  
  13118. raiserror(15339,-1,-1,'sp_MSfast_delete_trans')
  13119. GO
  13120. CREATE PROCEDURE sp_MSfast_delete_trans
  13121. as
  13122.     declare @retcode int
  13123.  
  13124.     EXEC @retcode = sp_MSdrop_snapshot_dirs
  13125.     if( @retcode <> 0 or @@error <> 0 )
  13126.         return 1
  13127.  
  13128.     truncate table MSrepl_commands
  13129.     truncate table MSrepl_transactions
  13130.  
  13131. GO
  13132.  
  13133. raiserror(15339,-1,-1,'sp_MSdelete_dodelete')
  13134. go
  13135. -- New delete stored procedure WITH RECOMPILE
  13136. CREATE PROCEDURE sp_MSdelete_dodelete
  13137.     @publisher_database_id int,
  13138.     @max_xact_seqno varbinary(16),
  13139.     @last_xact_seqno varbinary(16),
  13140.     @last_log_xact_seqno varbinary(16)
  13141. WITH RECOMPILE
  13142.     as
  13143.         delete MSrepl_transactions WITH (PAGLOCK) from MSrepl_transactions where
  13144.                 publisher_database_id = @publisher_database_id and
  13145.                 xact_seqno <= @max_xact_seqno and
  13146.                 xact_seqno <> @last_xact_seqno and
  13147.                 xact_seqno <> @last_log_xact_seqno and
  13148.                 -- use nolock to avoid deadlock
  13149.                 not exists (select * from MSrepl_commands c (nolock) where
  13150.                     c.publisher_database_id = @publisher_database_id and
  13151.                     c.xact_seqno = MSrepl_transactions.xact_seqno)
  13152. GO
  13153.  
  13154. raiserror(15339,-1,-1,'sp_MSdelete_publisherdb_trans')
  13155. GO
  13156. CREATE PROCEDURE sp_MSdelete_publisherdb_trans
  13157.     @publisher_database_id int,
  13158.     @max_xact_seqno varbinary(16),
  13159.     @max_cutoff_time datetime,
  13160.     @num_transactions int OUTPUT,
  13161.     @num_commands int OUTPUT
  13162.     as
  13163.  
  13164.     set nocount on
  13165.     
  13166.     declare @snapshot_bit int
  13167.     declare @replpost_bit int
  13168.     declare @directory_type int
  13169.     declare @alt_directory_type int
  13170.     declare @scriptexec_type int
  13171.     declare @last_xact_seqno varbinary(16)
  13172.     declare @last_log_xact_seqno varbinary(16)
  13173.     declare @max_immediate_sync_seqno varbinary(16)
  13174.     declare @dir nvarchar(512)
  13175.     declare @row_count int
  13176.     declare @batchsize int
  13177.     declare @retcode int            /* Return value of xp_cmdshell */
  13178.     declare @has_immediate_sync bit
  13179.     declare @xact_seqno varbinary(16)
  13180.     declare @command_id int
  13181.     declare @type int
  13182.     declare @directory nvarchar(1024)
  13183.  
  13184.     select @snapshot_bit = 0x80000000
  13185. select @replpost_bit = 0x40000000
  13186.     select @directory_type = 7
  13187.     select @alt_directory_type = 25
  13188. select @scriptexec_type = 46
  13189.     select @num_transactions = 0
  13190.     select @num_commands = 0
  13191.  
  13192.     -- If transactions for immediate_sync publications will not be cleanup up until
  13193.     -- they are older that max retention, except for snapshot transactions.
  13194.     -- Snapshot transactions for immediate_sync publication will be cleanup up if it is
  13195.     -- not used by any subscriptions (including virtual and virtual immediate_syncymous
  13196.     -- subscriptions. Both will be reset by snapshot agent every time if the 
  13197.     -- publication is snapshot type.) The special logic for snapshot transactions
  13198.     -- is mostly for snapshop publications. It is to cleaup up the snapshot files 
  13199.     -- ASAP and not to wait for max retention.
  13200.     -- We don't need to do this for non-immediate_syncymous publications since the snapshot
  13201.     -- trans for them will be removed as soon as they are distributed and min '
  13202.     -- retention is reached.
  13203.  
  13204.     -- Detect if there are immediate_syncymous publications in this publishing db.
  13205.     if exists (select * from MSsubscriptions where
  13206.             publisher_database_id = @publisher_database_id and
  13207.             subscriber_id < 0)
  13208.         select @has_immediate_sync = 1
  13209.     else
  13210.         select @has_immediate_sync = 0
  13211.  
  13212.     if @has_immediate_sync = 1
  13213.     begin
  13214.         -- if @max_immediate_sync_seqno is null, not row will be deleted based on that.
  13215.         select @max_immediate_sync_seqno = max(xact_seqno) from MSrepl_transactions where
  13216.             publisher_database_id = @publisher_database_id and
  13217.             entry_time <= @max_cutoff_time
  13218.     end
  13219.  
  13220.     -- Note delete commands first since transaction table will be used for
  13221.     -- geting @max_xact_seqno (see sp_MSmaximum_cleanup_seqno).
  13222.     -- Delete all directories stored in directory command.
  13223.     if @has_immediate_sync = 0
  13224.         declare  hCdirs  CURSOR LOCAL FAST_FORWARD FOR select CONVERT(nvarchar(512), command),
  13225.             xact_seqno, command_id, type
  13226.             from MSrepl_commands where
  13227.             publisher_database_id = @publisher_database_id and
  13228.             xact_seqno <= @max_xact_seqno and   
  13229.             ((type & ~@snapshot_bit) = @directory_type or
  13230.             (type & ~@snapshot_bit) = @alt_directory_type)
  13231.         for read only
  13232.     else
  13233.         declare  hCdirs  CURSOR LOCAL FAST_FORWARD FOR select CONVERT(nvarchar(512), command),
  13234.             xact_seqno, command_id, type
  13235.             from MSrepl_commands c where
  13236.             publisher_database_id = @publisher_database_id and
  13237.             ((type & ~@snapshot_bit) = @directory_type  or
  13238.              (type & ~@snapshot_bit) = @alt_directory_type or
  13239.              (type & ~@replpost_bit) = @scriptexec_type) and
  13240.             xact_seqno <= @max_xact_seqno and  
  13241.             (
  13242.             -- Select the row if it is older than max retention.
  13243.             xact_seqno <= @max_immediate_sync_seqno or 
  13244.             -- Select the row if it is not used by any subscriptions.
  13245.             not exists (select * from MSsubscriptions s where
  13246.                 s.publisher_database_id = @publisher_database_id and
  13247.                 s.subscription_seqno = c.xact_seqno) OR
  13248.             -- Select the row if it is not for immediate_sync publications
  13249.             -- Note: directory command have article id 0 so it is not useful
  13250.             not exists (select * from MSpublications p where
  13251.                 p.publication_id = (select top 1 s.publication_id 
  13252.                     from MSsubscriptions s where
  13253.                     s.publisher_database_id = @publisher_database_id and
  13254.                     s.subscription_seqno = c.xact_seqno) and
  13255.                 p.immediate_sync = 1)
  13256.             )
  13257.         for read only
  13258.  
  13259.     open hCdirs
  13260.     fetch hCdirs into @dir, @xact_seqno, @command_id, @type
  13261.     while (@@fetch_status <> -1)
  13262.     begin
  13263.     if( (@type & ~@replpost_bit) = @scriptexec_type) -- script exec command, need to map to the right path.
  13264.         select @dir = left(@dir,len(@dir) - charindex(N'\', reverse(@dir)))        
  13265.     -- Need to map unc to local drive for access problem
  13266.         exec @retcode = dbo.sp_MSreplremoveuncdir @dir
  13267.         /* Abort the operation if the delete fails */
  13268.         if (@retcode <> 0 or @@error <> 0)
  13269.             return (1)
  13270.  
  13271.         delete MSrepl_commands where 
  13272.             publisher_database_id = @publisher_database_id and
  13273.             xact_seqno = @xact_seqno and
  13274.             command_id = @command_id
  13275.         -- Update output parameter
  13276.         select @num_commands = @num_commands + @@rowcount
  13277.  
  13278.         fetch hCdirs into @dir, @xact_seqno, @command_id, @type
  13279.     end
  13280.     close hCdirs
  13281.     deallocate hCdirs
  13282.  
  13283.  
  13284.     -- Delete all commans less than or equal to the @max_xact_seqno
  13285.     -- Delete in batch to reduce the transaction size
  13286.     set rowcount 2000
  13287.     WHILE 1 = 1
  13288.     BEGIN
  13289.         if @has_immediate_sync = 0
  13290.             DELETE MSrepl_commands WITH (PAGLOCK) where
  13291.                 publisher_database_id = @publisher_database_id and
  13292.                 xact_seqno <= @max_xact_seqno
  13293.         else
  13294.             -- Use nolock hint on subscription table to avoid deadlock
  13295.             -- with snapshot agent.
  13296.             DELETE MSrepl_commands WITH (PAGLOCK) where
  13297.                 publisher_database_id = @publisher_database_id and
  13298.                 xact_seqno <= @max_xact_seqno and
  13299.                 -- Don't delete directory commands. It is deleted ealier.
  13300.                 -- We have to do this because we use (nolock) hint. we have to make sure
  13301.                 -- we don't delete dir command when the file is not cleaned up in the code
  13302.                 -- above.
  13303.                 (type & ~@snapshot_bit) <> @directory_type and
  13304.                 (
  13305.                 -- Select the row if it is older than max retention.
  13306.                 xact_seqno <= @max_immediate_sync_seqno or 
  13307.                 -- Select the row if it is not for immediate_sync article
  13308.                 -- We know the command is for immediate_sync publication if
  13309.                 -- the snapshot tran include articles that has virtual
  13310.                 -- subscritptions. (use subscritpion table to avoid join with
  13311.                 -- article and publication table)
  13312.                 not exists (select * from MSsubscriptions s (nolock) where
  13313.                     s.publisher_database_id = @publisher_database_id and
  13314.                     s.article_id = MSrepl_commands.article_id and
  13315.                     s.subscriber_id < 0) or
  13316.                 -- Select the row if it is snapshot tran and 
  13317.                 -- not used by any subscriptions.
  13318.                 -- Delete the snapshot commands if there's no subscriptions that are not 
  13319.                 -- virtual anonymous have smaller or equal subscription_seqno than 
  13320.                 -- the command's xact_seqno.
  13321.                 ((type & @snapshot_bit) <> 0 and
  13322.                 not exists (select * from MSsubscriptions s (nolock) where
  13323.                     s.publisher_database_id = @publisher_database_id and
  13324.                     s.subscription_seqno <= MSrepl_commands.xact_seqno and
  13325.                     s.subscriber_id <> -2))
  13326.                 )
  13327.  
  13328.         select @row_count = @@rowcount
  13329.         -- Update output parameter
  13330.         select @num_commands = @num_commands + @row_count
  13331.     
  13332.         IF @row_count = 0 -- passed the result set.  We're done
  13333.             BREAK
  13334.     END
  13335.  
  13336.     -- Optimized query to get the max transaction row
  13337.     set rowcount 1
  13338.     select @last_log_xact_seqno = xact_seqno from MSrepl_transactions
  13339.         where
  13340.             publisher_database_id = @publisher_database_id and
  13341.             xact_id <> 0x0  -- not initial sync transaction
  13342.             order by xact_seqno desc
  13343.  
  13344.     select @last_xact_seqno = xact_seqno from MSrepl_transactions
  13345.         where
  13346.             publisher_database_id = @publisher_database_id
  13347.             order by xact_seqno desc
  13348.     set rowcount 0
  13349.  
  13350.     -- Remove all transactions less than or equal to the @max_xact_seqno and leave the 
  13351.     -- last transaction row
  13352.     -- Note @max_xact_seqno might be null, in this case don't do any thing.
  13353.     -- Delete in batchs to reduce the transaction size
  13354.     set rowcount 5000
  13355.     -- Delete all commans less than or equal to the @max_xact_seqno
  13356.     -- Delete  rows to reduce the transaction size
  13357.     WHILE 1 = 1
  13358.     BEGIN
  13359.         if @has_immediate_sync = 0
  13360.             delete MSrepl_transactions WITH (PAGLOCK) from MSrepl_transactions where
  13361.                 publisher_database_id = @publisher_database_id and
  13362.                 xact_seqno <= @max_xact_seqno and
  13363.                 xact_seqno <> @last_xact_seqno and
  13364.                 xact_seqno <> @last_log_xact_seqno
  13365.         else
  13366.             exec dbo.sp_MSdelete_dodelete @publisher_database_id, @max_xact_seqno, 
  13367.                 @last_xact_seqno, @last_log_xact_seqno 
  13368.  
  13369.         select @row_count = @@rowcount
  13370.  
  13371.         -- Update output parameter
  13372.         select @num_transactions = @num_transactions + @row_count
  13373.         if @row_count = 0
  13374.             BREAK
  13375.     END
  13376.     set rowcount 0
  13377. GO
  13378.  
  13379. raiserror(15339,-1,-1,'sp_MSmaximum_cleanup_seqno')
  13380. go
  13381. CREATE PROCEDURE sp_MSmaximum_cleanup_seqno
  13382.     @publisher_database_id int,
  13383.     @min_cutoff_time datetime,
  13384.     @max_cleanup_xact_seqno varbinary(16) OUTPUT
  13385.     as
  13386.  
  13387.     declare @min_sub_xact_seqno varbinary(16)
  13388.     declare @min_history_xact_seqno varbinary(16)
  13389.     declare @active int
  13390.     declare @initiated int
  13391.     declare @max_seqno varbinary(16)
  13392.     
  13393.     -- @max_seqn is to avoid warnging message from server on null values in aggregation.
  13394.     select @max_seqno = 0xffffffffffffffffffffffffffffffff
  13395.  
  13396.     set nocount on
  13397.  
  13398.     select @active = 2
  13399.     select @initiated = 3
  13400.  
  13401.     select  
  13402.         -- Get the min history xact_seqno that are large then or equal to starting
  13403.         -- sub seqno
  13404.         @min_history_xact_seqno = min(seqno.xact_seqno), 
  13405.         -- Get the min starting sub xact_seqno without larger history xact_seqno or without
  13406.         -- any history at all.
  13407.         @min_sub_xact_seqno = min(seqno.subscription_seqno)
  13408.         from
  13409.             -- seqno stores min sub seqno , min history seqno and choose_sub
  13410.             (select 
  13411.                 -- If history is larger and it is not null
  13412.                 -- use history.
  13413.                 case when dh.xact_seqno > = sh.subscription_seqno 
  13414.                 then dh.xact_seqno
  13415.                 -- Don't use dh in else
  13416.                 else @max_seqno
  13417.                 end,
  13418.  
  13419.                 -- If history is larger and it is not null
  13420.                 -- use history.
  13421.                 case when dh.xact_seqno > = sh.subscription_seqno 
  13422.                 -- Don't use sh
  13423.                 then @max_seqno
  13424.                 else sh.subscription_seqno
  13425.                 end
  13426.  
  13427.                 from 
  13428.                     (select s.agent_id, s.subscription_seqno, max(isnull(h.timestamp,0x00))
  13429.                     from 
  13430.                         -- s stores the agent id and min subscription_seqno for
  13431.                         -- active subscriptions on non immediate_sync subscriptions
  13432.                         (select a.id, min(s2.subscription_seqno) from
  13433.                             MSsubscriptions s2 
  13434.                             join MSdistribution_agents a
  13435.                             on (a.id = s2.agent_id) 
  13436.                             where
  13437.                             s2.status in( @active, @initiated ) and
  13438.                             /* Note must filter out virtual anonymous agents !!!
  13439.                                 a.subscriber_id <> @virtual_anonymous and */
  13440.                             -- filter out subscriptions to immediate_sync publications
  13441.                             not exists (select * from MSpublications p where
  13442.                                 s2.publication_id = p.publication_id and
  13443.                                 p.immediate_sync = 1) and
  13444.                             a.publisher_database_id = @publisher_database_id
  13445.                             group by a.id)
  13446.                         s (agent_id, subscription_seqno)
  13447.                         left join MSdistribution_history h
  13448.                         on (h.agent_id = s.agent_id)
  13449.                         group by s.agent_id, s.subscription_seqno)
  13450.                     sh (agent_id, subscription_seqno, timestamp)
  13451.                     left join MSdistribution_history dh 
  13452.                     on (dh.agent_id = sh.agent_id and dh.timestamp = sh.timestamp))
  13453.                     seqno (xact_seqno, subscription_seqno)
  13454.  
  13455.  
  13456.  
  13457. /*  This version might be faster.. Need experiments.
  13458.  
  13459.  
  13460.     -- Get the min history xact_seqno that are large then or equal to starting
  13461.     -- sub seqno
  13462.     select @min_history_xact_seqno = min(dh.xact_seqno) from
  13463.         -- h stores the agent_ids and last xact_seqno for the publisher_db 
  13464.         (select h2.agent_id, max(h2.timestamp) 
  13465.             from MSdistribution_history h2
  13466.             join MSdistribution_agents a
  13467.                 on (a.id = h2.agent_id)
  13468.             where
  13469.                 a.publisher_database_id = @publisher_database_id
  13470.                 group by h2.agent_id)
  13471.         h (agent_id, timestamp) 
  13472.         -- dh stores timestamp and xact_seqno association
  13473.         join MSdistribution_history dh 
  13474.             on (dh.agent_id = h.agent_id and dh.timestamp = h.timestamp)
  13475.         where   
  13476.             -- Only select history xact seqno larger then or equal to
  13477.             -- subscription start up seqno.
  13478.             -- Excluding agents with no active subscriptions. 
  13479.             dh.xact_seqno >=
  13480.                 (select min(s.subscription_seqno) from MSsubscritions s where
  13481.                     -- Including anonymous agents
  13482.                     (s.agent_id = a. agent_id or s.agent_id = a.anonymous_agent_id) and
  13483.                     s.status = @active)
  13484.             
  13485.     -- Get the min starting sub xact_seqno without larger history xact_seqno or without
  13486.     -- any history at all.
  13487.     -- This will happen if the subscription is reinited
  13488.     -- excluding virtual anonymous subscriptions.
  13489.     select @min_sub_xact_seqno = min(s.subscription_seqno) from
  13490.         MSsubscriptions s
  13491.         -- left join so that subscription without history will be included. 
  13492.         left join ((select h2.agent_id, max(h2.timestamp) 
  13493.             from MSdistribution_history h2
  13494.             join MSdistribution_agents a
  13495.                 on (a.id = h2.agent_id)
  13496.             where
  13497.                 a.publisher_database_id = @publisher_database_id
  13498.                 group by h2.agent_id)
  13499.             h (agent_id, timestamp) 
  13500.         -- dh stores timestamp and xact_seqno association
  13501.         join MSdistribution_history dh 
  13502.             on (dh.agent_id = h.agent_id and dh.timestamp = h.timestamp))
  13503.             on (s.agent_id = h.agent_id)
  13504.         where
  13505.         s.status = @active and
  13506.         s.subscriber_id <> @virtual_anonymous and
  13507.         s.publisher_database_id = @publisher_database_id and
  13508.         -- select only subs that has a larger starting seqno than history last seqno
  13509.         -- or with no history
  13510.         s.subscription_seqno > isnull(dh.xact_seqno, 0x0)
  13511. */  
  13512.     
  13513.     /* 
  13514.     ** Optimized query to get the maximum cleanup xact_seqno
  13515.     */
  13516.     /* 
  13517.     ** If the query below returns nothing, nothing can be deleted.
  13518.     ** Reset @max_cleanup_xact_seqno to 0.
  13519.     */
  13520.     select @max_cleanup_xact_seqno = 0x00
  13521.     -- Use top 1 to avoid warning message of "Null in aggregate..." which will make
  13522.     -- sqlserver agent job having failing status
  13523.     select top 1 @max_cleanup_xact_seqno = xact_seqno
  13524.         from MSrepl_transactions
  13525.         where
  13526.             publisher_database_id = @publisher_database_id and
  13527.             (@min_history_xact_seqno IS NULL or
  13528.             -- Delete the history xact since it is distributed already.
  13529.             xact_seqno <= @min_history_xact_seqno) and
  13530.             (@min_sub_xact_seqno IS NULL or
  13531.             -- Don't delete the sub xact since it is not distributed yet.
  13532.             xact_seqno < @min_sub_xact_seqno) and
  13533.             entry_time <= @min_cutoff_time
  13534.             order by xact_seqno desc
  13535.  
  13536. GO
  13537.  
  13538. raiserror(15339,-1,-1,'sp_MSdistribution_delete')
  13539. go
  13540. CREATE PROCEDURE sp_MSdistribution_delete
  13541.     @retention int = 0,
  13542.     -- Used for anon publications.
  13543.     @max_cutoff_time datetime
  13544.     as
  13545.     declare @min_cutoff_time datetime
  13546.     declare @subscriber sysname
  13547.     declare @subscriber_db sysname
  13548.     declare @max_cleanup_xact_seqno varbinary(16)   
  13549.     declare @num_transactions int
  13550.     declare @num_commands int
  13551.     declare @start_time datetime
  13552.     declare @num_seconds int
  13553.     declare @rate int
  13554.     declare @retcode int
  13555.     declare @publisher_database_id int
  13556.  
  13557.     set nocount on
  13558.  
  13559.     select @num_transactions = 0
  13560.     select @num_commands = 0
  13561.  
  13562.     select @start_time = getdate()
  13563.     select @min_cutoff_time = dateadd(hour, -@retention, getdate())
  13564.  
  13565.     -- For each publisher/publisherdb pair do cleanup
  13566.     declare hC CURSOR LOCAL FAST_FORWARD FOR select distinct publisher_database_id
  13567.         from MSrepl_transactions
  13568.         for read only
  13569.     -- With ANSI Defaults ON, the cursor will automatically
  13570.     -- be closed on commit.   Since this proc gets called recursively, 
  13571.     -- this can happen.  So check before opening. 
  13572.     IF CURSOR_STATUS('local','hC') = -1
  13573.     open hC
  13574.  
  13575.     fetch hC into @publisher_database_id 
  13576.     while (@@fetch_status <> -1)
  13577.     begin
  13578.  
  13579.         -- Find the maximum transaction to delete
  13580.         exec @retcode = dbo.sp_MSmaximum_cleanup_seqno @publisher_database_id, @min_cutoff_time, @max_cleanup_xact_seqno OUTPUT
  13581.         if @retcode <> 0
  13582.             goto FAIL           
  13583.  
  13584.         -- Delete transactions and commands
  13585.         exec @retcode = dbo.sp_MSdelete_publisherdb_trans @publisher_database_id, 
  13586.             @max_cleanup_xact_seqno, @max_cutoff_time,
  13587.             @num_transactions OUTPUT, @num_commands OUTPUT
  13588.         if @retcode <> 0
  13589.             goto FAIL
  13590.  
  13591.         IF CURSOR_STATUS('local','hC') = -1
  13592.             open hC
  13593.         
  13594.         fetch hC into @publisher_database_id 
  13595.     end
  13596.     close hC
  13597.     deallocate hC
  13598.  
  13599.     select @num_seconds = datediff(second, @start_time, getdate())
  13600.     if @num_seconds <> 0 
  13601.       select @rate = (@num_transactions+@num_commands)/@num_seconds
  13602.     else
  13603.       select @rate = 0
  13604.  
  13605.    RAISERROR(21010, 10, -1, @num_transactions, @num_commands, @num_seconds, @rate)
  13606.  
  13607.    return 0
  13608.  
  13609. FAIL:
  13610.    close hC
  13611.    deallocate hC
  13612.    return 1
  13613. GO
  13614.  
  13615.  
  13616. raiserror(15339,-1,-1,'sp_MSdistribution_cleanup')
  13617. GO
  13618. CREATE PROCEDURE sp_MSdistribution_cleanup
  13619.     @min_distretention int = 0,
  13620.     @max_distretention int = 24
  13621.     as
  13622.  
  13623.     declare @retcode int
  13624.     declare @agent_name nvarchar(255)
  13625.     declare @agent_type nvarchar(100)
  13626.     declare @message nvarchar(255)
  13627.     declare @cutoff_time datetime
  13628.  
  13629.      -- Check for invalid parameter values 
  13630.     if @min_distretention < 0 or @max_distretention < 0
  13631.     begin
  13632.         RAISERROR(14106, 16, -1)
  13633.         return (1)
  13634.     end
  13635.  
  13636.     -- Note: we need to use the same cut_off time for sp_MSsubscription_cleanup
  13637.     -- and sp_MSdistribution_delete since sp_MSsubscription_cleanup need to disable
  13638.     -- all the dist agents that are lag behind (their pending trans will be removed)
  13639.     select @cutoff_time = dateadd(hour, -@max_distretention, getdate())
  13640.  
  13641.     -- Deactive any subscriptions which have been inactive beyond the maximum retention
  13642.     exec @retcode = dbo.sp_MSsubscription_cleanup @cutoff_time
  13643.     if @retcode <> 0
  13644.         goto FAIL
  13645.  
  13646.     -- Remove transactions and commands
  13647.     exec @retcode = dbo.sp_MSdistribution_delete @min_distretention, 
  13648.         -- used to cleanup trans for anon publications.
  13649.         @cutoff_time
  13650.     if @retcode <> 0
  13651.         goto FAIL
  13652.  
  13653.     -- Update statistics on cleaned tables with norecompute flag
  13654.     -- to both update the statistics periodically and 
  13655.     -- to ensure that they are not updated too frequently
  13656.     -- since this slows performance.
  13657.     --
  13658.     -- Update statistics can only be performed when not in
  13659.     -- not in a tracation so predicate by transaction level
  13660.     -- to avoid error.
  13661.     --
  13662.     if @@trancount = 0
  13663.     begin
  13664.         UPDATE STATISTICS MSrepl_commands WITH NORECOMPUTE
  13665.         UPDATE STATISTICS MSrepl_transactions WITH NORECOMPUTE
  13666.     end
  13667.  
  13668.     return(0)
  13669.  
  13670. FAIL:
  13671.     -- Raise the Agent Failure error
  13672.     set @agent_type  = formatmessage(20543)
  13673.     SELECT @agent_name = db_name() + @agent_type
  13674.     set @message  = formatmessage(20552)
  13675.     exec dbo.sp_MSrepl_raiserror @agent_type, @agent_name, 5, @message
  13676.     return (1)  
  13677.  
  13678. GO
  13679.  
  13680. raiserror(15339,-1,-1,'sp_MShistory_cleanup')
  13681. GO
  13682. CREATE PROCEDURE sp_MShistory_cleanup
  13683. @history_retention int = 24
  13684. as
  13685.     declare @cutoff_time datetime
  13686.     declare @start_time datetime
  13687.     declare @num_snapshot_rows int
  13688.     declare @num_logreader_rows int
  13689.     declare @num_distribution_rows int
  13690.     declare @num_replerror_rows int
  13691.     declare @num_queuereader_rows int
  13692.         ,@num_alert_rows int
  13693.     declare @num_milliseconds int
  13694.     declare @num_seconds float
  13695.     declare @seconds_str nvarchar(10)
  13696.     declare @rate int
  13697.     declare @retcode int
  13698.     declare @total_rows int
  13699.     declare @num_merge_rows int
  13700.     declare @agent_name nvarchar(255)
  13701.     declare @agent_type nvarchar(100)
  13702.     declare @message nvarchar(255)
  13703.     declare @agent_id int
  13704.     declare @temp_error int
  13705.  
  13706.     set nocount on
  13707.  
  13708.     /* Check for invalid parameter values */
  13709.     if @history_retention < 0
  13710.     BEGIN
  13711.         RAISERROR(14106, 16, -1)
  13712.         RETURN (1)
  13713.     END
  13714.     
  13715.     -- Get start time for statistics at the end
  13716.     select @start_time = getdate()
  13717.  
  13718.     select @num_snapshot_rows = 0
  13719.     select @num_logreader_rows = 0
  13720.     select @num_distribution_rows = 0
  13721.     select @num_merge_rows = 0
  13722.     select @num_replerror_rows = 0
  13723.     select @num_queuereader_rows = 0
  13724.  
  13725.     -- Get cutoff time
  13726.     select @cutoff_time = dateadd(hour, -@history_retention, getdate())
  13727.  
  13728.     -- Delete sp_MSsnapshot_history (leave at least one row for monitoring)
  13729.     delete MSsnapshot_history where 
  13730.         time <= @cutoff_time and
  13731.         timestamp not in (select max(timestamp) from MSsnapshot_history 
  13732.             group by agent_id)
  13733.     select @temp_error = @@error, @num_snapshot_rows = @num_snapshot_rows + @@rowcount
  13734.     if @temp_error <> 0
  13735.         goto FAIL
  13736.  
  13737.     -- Delete sp_MSsnapshot_history that no longer has an MSsnapshot_agent entry
  13738.     delete from MSsnapshot_history where not exists (select * from MSsnapshot_agents
  13739.         where id = agent_id)
  13740.     select @temp_error = @@error, @num_snapshot_rows = @num_snapshot_rows + @@rowcount
  13741.     if @temp_error <> 0
  13742.         goto FAIL
  13743.  
  13744.     -- Delete sp_MSlogreader_history (leave at least one row for monitoring)
  13745.     delete MSlogreader_history where 
  13746.         time <= @cutoff_time and
  13747.         timestamp not in (select max(timestamp) from MSlogreader_history 
  13748.             group by agent_id)
  13749.     select @temp_error = @@error, @num_logreader_rows = @num_logreader_rows + @@rowcount
  13750.     if @temp_error <> 0
  13751.         goto FAIL
  13752.  
  13753.     -- Delete sp_MSlogreader_history that no longer has an MSlogreader_agent entry
  13754.     delete from MSlogreader_history where not exists (select * from MSlogreader_agents
  13755.         where id = agent_id)
  13756.     select @temp_error = @@error, @num_logreader_rows = @num_logreader_rows + @@rowcount
  13757.     if @temp_error <> 0
  13758.         goto FAIL
  13759.  
  13760.     -- Delete sp_MSdistribution_history (leave at least one row for monitoring)
  13761.     -- Leave last record ONLY if the agent is not anonymous.  The current logic is to remove all history for anonymous
  13762.     -- subscription, the agent definition will also be removed below.
  13763.     delete MSdistribution_history where 
  13764.         time <= @cutoff_time and
  13765.         timestamp not in (select max(timestamp) from MSdistribution_history group by agent_id)
  13766.     select @temp_error = @@error, @num_distribution_rows = @num_distribution_rows + @@rowcount
  13767.     if @temp_error <> 0
  13768.         goto FAIL
  13769.  
  13770.     -- Delete sp_MSdistribution_history that no longer has an MSdistribution_agent entry
  13771.     delete MSdistribution_history from MSdistribution_history dh where not exists (select * from MSdistribution_agents
  13772.         where id = dh.agent_id)
  13773.     select @temp_error = @@error, @num_distribution_rows = @num_distribution_rows + @@rowcount
  13774.     if @temp_error <> 0
  13775.         goto FAIL
  13776.  
  13777.     -- Delete MSqreader_history (leave at least one row for monitoring)
  13778.     delete MSqreader_history where 
  13779.         time <= @cutoff_time and
  13780.         timestamp not in (select max(timestamp) from MSqreader_history 
  13781.             group by agent_id)
  13782.     select @temp_error = @@error, @num_queuereader_rows = @num_queuereader_rows + @@rowcount
  13783.     if @temp_error <> 0
  13784.         goto FAIL
  13785.  
  13786.     -- Delete sp_MSlogreader_history that no longer has an MSlogreader_agent entry
  13787.     delete from MSqreader_history where not exists (select * from MSqreader_agents
  13788.         where id = agent_id)
  13789.     select @temp_error = @@error, @num_queuereader_rows = @num_queuereader_rows + @@rowcount
  13790.     if @temp_error <> 0
  13791.         goto FAIL
  13792.  
  13793.     -- Delete sp_MSmerge_history (leave at least one row for monitoring)
  13794.     -- Leave last record ONLY if the agent is not anonymous.  The current logic is to remove all history for anonymous
  13795.     -- subscription, the agent definition will also be removed below.
  13796.     delete from MSmerge_history where 
  13797.         time <= @cutoff_time and
  13798.         timestamp not in (select max(timestamp) from MSmerge_history group by agent_id)
  13799.     select @temp_error = @@error, @num_merge_rows = @num_merge_rows + @@rowcount
  13800.     if @temp_error <> 0
  13801.         goto FAIL
  13802.  
  13803.     -- Delete sp_MSmerge_history that no longer has an MSmerge_agent entry
  13804.     delete from MSmerge_history where not exists (select * from MSmerge_agents where id = agent_id)
  13805.     select @temp_error = @@error, @num_merge_rows = @num_merge_rows + @@rowcount
  13806.     if @temp_error <> 0
  13807.         goto FAIL
  13808.  
  13809.     -- Delete MSrepl_error entries
  13810.     delete from MSrepl_errors where time <= @cutoff_time 
  13811.     select @temp_error = @@error, @num_replerror_rows = @@rowcount
  13812.     if @temp_error <> 0
  13813.         goto FAIL
  13814.     
  13815.     -- Delete sysreplicationalerts table
  13816.     delete from msdb..sysreplicationalerts where time <= @cutoff_time 
  13817.     select @temp_error = @@error, @num_alert_rows = @@rowcount
  13818.     if @temp_error <> 0
  13819.         goto FAIL
  13820.  
  13821.     -- Calculate statistics for number of rows deleted
  13822.     select @num_milliseconds = datediff(millisecond, @start_time, getdate())
  13823.     if @num_milliseconds <> 0
  13824.         select @num_seconds = @num_milliseconds*1.0/1000
  13825.     else 
  13826.         select @num_seconds = 0
  13827.  
  13828.     select @total_rows = @num_snapshot_rows + @num_logreader_rows + 
  13829.         @num_distribution_rows +  @num_merge_rows + @num_replerror_rows + @num_alert_rows
  13830.  
  13831.     if @num_seconds <> 0 
  13832.         select @rate = @total_rows/@num_seconds
  13833.     else
  13834.         select @rate = @total_rows
  13835.  
  13836.     select @seconds_str = CONVERT(nchar(10), @num_seconds)
  13837.  
  13838.     RAISERROR(14108, 10, -1, @num_merge_rows, 'MSmerge_history')
  13839.     RAISERROR(14108, 10, -1, @num_snapshot_rows, 'MSsnapshot_history')
  13840.     RAISERROR(14108, 10, -1, @num_logreader_rows, 'MSlogreader_history')
  13841.     RAISERROR(14108, 10, -1, @num_distribution_rows, 'MSdistribution_history')
  13842.     RAISERROR(14108, 10, -1, @num_queuereader_rows, 'MSqreader_history')
  13843.     RAISERROR(14108, 10, -1, @num_replerror_rows, 'MSrepl_errors')
  13844.     RAISERROR(14108, 10, -1, @num_alert_rows, 'sysreplicationalerts')
  13845.     RAISERROR(14149, 10, -1, @total_rows, @seconds_str, @rate)
  13846.     
  13847.     return 0
  13848.  
  13849. FAIL:
  13850.     -- Raise the Agent Failure error
  13851.     set @agent_type  = formatmessage(20544)
  13852.     SELECT @agent_name = db_name() + @agent_type
  13853.     set @message  = formatmessage(20553)
  13854.     exec dbo.sp_MSrepl_raiserror @agent_type, @agent_name, 5, @message
  13855.  
  13856.     return (1)
  13857.  
  13858. GO
  13859.  
  13860. raiserror(15339,-1,-1,'sp_MSget_repl_version')
  13861. GO
  13862. CREATE PROCEDURE sp_MSget_repl_version
  13863. @major_version int = 0 OUTPUT,
  13864. @minor_version int = 0 OUTPUT,
  13865. @revision int = 0 OUTPUT
  13866.  
  13867. as
  13868. SELECT @major_version = major_version,
  13869.        @minor_version = minor_version,
  13870.        @revision = revision FROM MSrepl_version
  13871. GO
  13872.  
  13873. raiserror(15339,-1,-1,'sp_MSenum_subscriptions')
  13874. GO
  13875. create procedure sp_MSenum_subscriptions
  13876. @publisher sysname,
  13877. @publisher_db sysname,
  13878. @publication sysname,
  13879. @exclude_anonymous bit = 0
  13880. as
  13881.  
  13882.     declare @subscriber sysname
  13883.     declare @subscriber_id smallint
  13884.     declare @subscriber_db sysname
  13885.     declare @subscriber_name sysname
  13886.     declare @type int
  13887.     declare @status int
  13888.     declare @distribution_agent nvarchar(100)
  13889.     declare @publisher_id smallint
  13890.     declare @independent_agent bit
  13891.     declare @offload_enabled bit
  13892.     declare @offload_server sysname 
  13893.  
  13894.     declare @start_time nvarchar(24)
  13895.     declare @time nvarchar(24)
  13896.     declare @duration int
  13897.     declare @comments nvarchar(255)
  13898.     declare @delivery_time int
  13899.     declare @delivered_transactions int
  13900.     declare @delivered_commands int
  13901.     declare @average_commands int
  13902.     declare @delivery_rate int
  13903.     declare @delivery_latency int
  13904.     declare @error_id int
  13905.     declare @publication_id int
  13906.     declare @job_id binary(16)
  13907.     declare @agent_id int
  13908.     declare @local_job bit
  13909.     declare @profile_id int
  13910.     declare @last_timestamp binary(8)
  13911.             ,@subscriber_type tinyint
  13912.  
  13913.     set nocount on
  13914.  
  13915.     select @publisher_id = srvid from master..sysservers where
  13916.        UPPER(srvname) = UPPER(@publisher)
  13917.  
  13918.     select @publication_id = publication_id from MSpublications  where 
  13919.             publisher_id = @publisher_id and
  13920.             publisher_db = @publisher_db and
  13921.             publication = @publication and
  13922.             (publication_type = 0 or publication_type = 1)
  13923.  
  13924.     create table #subscriptions (subscriber sysname NOT NULL,  status int NOT NULL, 
  13925.         subscriber_db sysname NOT NULL,
  13926.         type tinyint NOT NULL, distribution_agent nvarchar(100) NOT NULL, last_action nvarchar(255) NULL, 
  13927.         action_time nvarchar(24) NULL, start_time nvarchar(24) NULL, duration int NULL, 
  13928.         delivery_rate float NULL,
  13929.         delivery_latency int NULL, delivered_transactions int NULL, 
  13930.         delivered_commands int NULL,
  13931.         delivery_time int NULL, average_commands int NULL, 
  13932.         error_id int NULL, 
  13933.         job_id binary(16) NULL, local_job bit NULL, profile_id int NOT NULL,
  13934.         agent_id int NOT NULL, last_timestamp binary(8) NOT NULL, offload_enabled bit NOT NULL, 
  13935.         offload_server sysname NULL, subscriber_type tinyint NULL)
  13936.     
  13937.     -- This is to force all queries to return rows ordered by job_id
  13938.     -- Note: There might be dist agents left for cleaning up sub, in this case
  13939.     -- they are not in sub table and we don't want to show them
  13940.     create unique clustered index ucsubscriptions ON #subscriptions (agent_id)
  13941.     declare hC CURSOR LOCAL FAST_FORWARD FOR select id, name, subscriber_id, subscriber_db,
  13942.         job_id, local_job, subscription_type, profile_id, subscriber_name, offload_enabled,
  13943.         offload_server 
  13944.         from MSdistribution_agents a
  13945.         where exists (select * from MSsubscriptions s where
  13946.             (a.id = s.agent_id or a.anonymous_agent_id = s.agent_id) and
  13947.             s.publisher_id = @publisher_id and
  13948.             s.publisher_db = @publisher_db and
  13949.             -- For 6.x publisher, we don't know the association between the publication
  13950.             -- and subscriptions. Show every dist agent under each publication.
  13951.             (s.publication_id = @publication_id or s.publication_id = 0 ) and
  13952.             (a.subscriber_id >= 0  or a.subscriber_id is NULL)) and 
  13953.             (@exclude_anonymous = 0 or a.anonymous_agent_id is null)
  13954.         for read only
  13955.  
  13956.     -- declare hC CURSOR LOCAL FAST_FORWARD FOR select a.id, a.name, a.subscriber_id, ms.subscriber_db,
  13957.     --  a.job_id, a.local_job, ms.subscription_type, a.profile_id, a.subscriber_name
  13958.     --    from MSdistribution_agents a, master..sysservers s, MSsubscriptions ms
  13959.     --    where
  13960.     --    a.publisher_id = @publisher_id and
  13961.     --    a.publisher_db = @publisher_db and
  13962.     --  (a.publication = @publication or a.publication = 'ALL') and
  13963.     --  a.subscriber_id >= 0 and
  13964.     --  ms.publisher_db = @publisher_db and
  13965.     --  ms.publication_id = @publication_id and
  13966.     --  ms.subscriber_id = a.subscriber_id and
  13967.     --  ms.subscriber_db = a.subscriber_db and
  13968.     --  s.srvid = ms.subscriber_id
  13969.     --  for read only
  13970.  
  13971.     open hC
  13972.     fetch hC into  @agent_id, @distribution_agent, @subscriber_id, @subscriber_db,
  13973.         @job_id, @local_job, @type, @profile_id, @subscriber_name, @offload_enabled, 
  13974.         @offload_server
  13975.     while (@@fetch_status <> -1)
  13976.     begin
  13977.         /* Stuff in the values for no history case */
  13978.         select @status = 0, 
  13979.             @start_time = NULL,
  13980.             @time = NULL, @duration = NULL, @comments = NULL,
  13981.             @delivery_time = NULL, @delivered_transactions = NULL,
  13982.             @delivered_commands = NULL, @average_commands = NULL,
  13983.             @delivery_rate = NULL, @delivery_latency = NULL,
  13984.             @error_id = NULL,
  13985.             @last_timestamp = 0x00000000
  13986.  
  13987.         -- Get the status of the agent
  13988.         select @status = runstatus, 
  13989.             @start_time = convert(nvarchar(12), start_time, 112) +
  13990.                           substring(convert(nvarchar(24), start_time, 121), 11, 13),
  13991.             @time = convert(nvarchar(12), time, 112) +
  13992.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  13993.             @duration = duration, 
  13994.             @comments = comments,
  13995.             @delivery_time = 0, @delivered_transactions = delivered_transactions,
  13996.             @delivered_commands = delivered_commands, @average_commands = average_commands,
  13997.             -- Note: return average rate here !!! delivery_rate column is current rate
  13998.             @delivery_rate = delivery_rate,
  13999.             @delivery_latency = delivery_latency,
  14000.             @error_id = error_id, @last_timestamp = timestamp
  14001.             from MSdistribution_history
  14002.             where
  14003.                 agent_id = @agent_id and
  14004.                 timestamp = (select max(timestamp) from MSdistribution_history 
  14005.                     where 
  14006.                     agent_id = @agent_id)
  14007.  
  14008.         -- For anonymous subscriptions, @subscriber_name is not NULL
  14009.          if @subscriber_name is NULL
  14010.          begin
  14011.             select @subscriber = srvname from master..sysservers where srvid=@subscriber_id
  14012.             select @subscriber_type = type from MSsubscriber_info where
  14013.                 UPPER(publisher) = UPPER(@publisher) and
  14014.                 UPPER(subscriber) = UPPER(@subscriber)
  14015.          end
  14016.          else 
  14017.          begin
  14018.             select @subscriber = @subscriber_name
  14019.             select @subscriber_db = @subscriber_db + '-' + convert(nvarchar(4), @agent_id)
  14020.             -- Don't know the subscriber type for anonymous
  14021.          end
  14022.  
  14023.         insert into #subscriptions values ( @subscriber, @status, @subscriber_db,
  14024.             @type, @distribution_agent, @comments, @time, @start_time, @duration,
  14025.             @delivery_rate, @delivery_latency, @delivered_transactions, 
  14026.             @delivered_commands,  @delivery_time, @average_commands,
  14027.             @error_id, @job_id, @local_job, @profile_id, @agent_id, @last_timestamp,
  14028.             @offload_enabled, @offload_server, @subscriber_type)
  14029.  
  14030.         fetch hC into  @agent_id, @distribution_agent, @subscriber_id, @subscriber_db,
  14031.             @job_id, @local_job, @type, @profile_id, @subscriber_name, @offload_enabled,
  14032.             @offload_server
  14033.       end
  14034.  
  14035.     select * from #subscriptions order by job_id asc 
  14036.  
  14037.     drop table #subscriptions
  14038.     close hC
  14039.     deallocate hC
  14040. go
  14041.  
  14042.  
  14043. raiserror(15339,-1,-1,'sp_MSIfExistsSubscription')
  14044. GO
  14045. create procedure sp_MSIfExistsSubscription
  14046. @publisher sysname,
  14047. @publisher_db sysname,
  14048. @publication sysname,
  14049. @type int /* replication type, 1 - transactional/snapshot, 2 - merge */
  14050. as
  14051.     declare @publisher_id smallint
  14052.     declare @publication_id int
  14053.  
  14054.     if @type not in (1,2)
  14055.     begin
  14056.         RAISERROR(21055, 16, -1, '@type','sp_MSIfExistsSubscription')
  14057.         RETURN (1)
  14058.     end
  14059.  
  14060.     set nocount on
  14061.  
  14062.     select @publisher_id = srvid from master..sysservers where
  14063.        UPPER(srvname) = UPPER(@publisher)
  14064.  
  14065.     if @type = 1
  14066.     begin
  14067.         select @publication_id = publication_id from MSpublications  where 
  14068.                 publisher_id = @publisher_id and
  14069.                 publisher_db = @publisher_db and
  14070.                 publication = @publication and
  14071.                 (publication_type = 0 or publication_type = 1)
  14072.     
  14073.         select TOP 1 1 from MSdistribution_agents a
  14074.             where exists (select * from MSsubscriptions s where
  14075.                 (a.id = s.agent_id or a.anonymous_agent_id = s.agent_id) and
  14076.                 s.publisher_id = @publisher_id and
  14077.                 s.publisher_db = @publisher_db and
  14078.                 -- For 6.x publisher, we don't know the association between the publication
  14079.                 -- and subscriptions. Show every dist agent under each publication.
  14080.                 (s.publication_id = @publication_id or s.publication_id = 0 ) and
  14081.                 (a.subscriber_id >= 0  or a.subscriber_id is NULL))
  14082.     end
  14083.     else
  14084.     begin
  14085.         select @publication_id = publication_id from MSpublications  where 
  14086.                 publisher_id = @publisher_id and
  14087.                 publisher_db = @publisher_db and
  14088.                 publication = @publication and
  14089.                 publication_type = 2 -- Merge 
  14090.     
  14091.         select TOP 1 1 from MSmerge_agents 
  14092.             where publisher_id = @publisher_id and 
  14093.                 publisher_db = @publisher_db and 
  14094.                 publication = @publication
  14095.     end
  14096. go
  14097.  
  14098.  
  14099. raiserror(15339,-1,-1,'sp_MSenum_snapshot')
  14100. go
  14101. create procedure sp_MSenum_snapshot
  14102. @name nvarchar(100) = '%',
  14103. @show_distdb bit = 0
  14104. as
  14105.     set nocount on
  14106.  
  14107.     declare @publisher sysname
  14108.     declare @publisher_db sysname
  14109.     declare @publication sysname
  14110.     declare @publication_id int
  14111.     declare @snapshot_agent nvarchar(100)
  14112.     declare @status int
  14113.     declare @start_time nvarchar(24)
  14114.     declare @time nvarchar(24)
  14115.     declare @duration int
  14116.     declare @comments nvarchar(255)
  14117.     declare @delivered_transactions int
  14118.     declare @delivered_commands int
  14119.     declare @delivery_rate int
  14120.     declare @publisher_id smallint
  14121.     declare @error_id int
  14122.     declare @job_id binary(16)
  14123.     declare @local_job bit
  14124.     declare @profile_id int
  14125.     declare @agent_id int
  14126.     declare @last_timestamp binary(8)
  14127.  
  14128.  
  14129.     create table #snapshot_agent (name nvarchar(100) NOT NULL, status int NOT NULL,
  14130.         publisher sysname NOT NULL, publisher_db sysname NOT NULL, publication sysname NOT NULL,
  14131.         start_time nvarchar(24)  NULL, time nvarchar(24)  NULL, duration int NULL, 
  14132.         comments nvarchar(255) NULL, delivered_transactions int NULL, delivered_commands int NULL,
  14133.         delivery_rate float  NULL, error_id int NULL, job_id binary(16) NULL, local_job bit NOT NULL,
  14134.         profile_id int NOT NULL, agent_id int NOT NULL, last_timestamp binary(8) NOT NULL)
  14135.   
  14136.  
  14137.     declare hC  CURSOR LOCAL FAST_FORWARD FOR
  14138.          select srvname, sa.publisher_db, sa.publication, sa.name, sa.publisher_id,
  14139.             sa.local_job, sa.job_id, sa.profile_id, sa.id
  14140.             from
  14141.             MSsnapshot_agents sa, master..sysservers
  14142.             where 
  14143.             name LIKE @name and
  14144.             srvid = sa.publisher_id
  14145.         for read only
  14146.  
  14147.     OPEN hC
  14148.     FETCH hC INTO @publisher, @publisher_db, @publication, @snapshot_agent, @publisher_id,
  14149.         @local_job, @job_id, @profile_id, @agent_id
  14150.     WHILE (@@fetch_status <> -1)
  14151.         begin
  14152.      
  14153.         -- Get the publication id
  14154.         select @publication_id = isnull(publication_id, 0) from MSpublications where
  14155.             publisher_id = @publisher_id and
  14156.             publisher_db = @publisher_db and
  14157.             publication = @publication
  14158.             
  14159.         -- Stuff in the values for no history case 
  14160.         select @status = 0, 
  14161.             @start_time = NULL,
  14162.             @time = NULL, @duration = NULL, @comments = NULL,
  14163.             @delivered_commands = NULL, 
  14164.             @delivery_rate = NULL, 
  14165.             @error_id = NULL,
  14166.             @last_timestamp = 0x00000000        
  14167.        
  14168.         -- Get the status of the agent
  14169.         select @status = runstatus, 
  14170.             @start_time = convert(nvarchar(12), start_time, 112) + 
  14171.                           substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  14172.             @time = convert(nvarchar(12), time, 112) + 
  14173.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  14174.             @duration = duration, 
  14175.             @comments = comments,
  14176.             @delivered_transactions = delivered_transactions,
  14177.             @delivered_commands = delivered_commands,
  14178.             @delivery_rate = delivery_rate, 
  14179.             @error_id = error_id, 
  14180.             @last_timestamp = timestamp
  14181.             from MSsnapshot_history
  14182.             where
  14183.             agent_id = @agent_id and
  14184.             timestamp = (select top 1 timestamp from MSsnapshot_history where           
  14185.                 agent_id = @agent_id
  14186.                 order by timestamp DESC) 
  14187.     
  14188.         insert into #snapshot_agent values (@snapshot_agent, @status, @publisher,
  14189.             @publisher_db, @publication, @start_time, @time, @duration, @comments,
  14190.             @delivered_transactions, @delivered_commands, @delivery_rate, @error_id, @job_id, 
  14191.             @local_job, @profile_id, @agent_id, @last_timestamp)
  14192.  
  14193.         FETCH hC INTO @publisher, @publisher_db, @publication, @snapshot_agent,
  14194.             @publisher_id, @local_job, @job_id, @profile_id, @agent_id
  14195.         end
  14196.  
  14197.     if @show_distdb = 0
  14198.         select * from #snapshot_agent 
  14199.     else 
  14200.         select 'dbname' = DB_NAME(), * from #snapshot_agent
  14201.  
  14202.     drop table #snapshot_agent
  14203.     close hC
  14204.     deallocate hC
  14205.  
  14206. GO
  14207.  
  14208. raiserror(15339,-1,-1,'sp_MSenum_snapshot_s')
  14209. go
  14210. create procedure sp_MSenum_snapshot_s
  14211. @name nvarchar(100),
  14212. @hours int = 0, /* @hours < 0 will return TOP 100 */
  14213. @session_type int = 1 /* Return all sessions */
  14214. as
  14215.     set nocount on
  14216.  
  14217.     declare @agent_id int
  14218.     declare @succeed int
  14219.     declare @retry int
  14220.     declare @failure int
  14221.     declare @min_time datetime
  14222.     declare @independent_agent bit
  14223.     declare @publisher_id smallint
  14224.     declare @publisher_db sysname
  14225.     declare @publication sysname
  14226.     declare @start_agent_comment nvarchar(100)
  14227.     declare @initializing int
  14228.     declare @latest_session_timestamps table (timestamp binary(8) primary key, action_count int)
  14229.  
  14230.     /* 
  14231.     ** Status const defined in sqlrepl.h 
  14232.     */
  14233.     select @succeed = 2
  14234.     select @retry = 5
  14235.     select @failure = 6
  14236.     select @initializing = 1
  14237.     select @start_agent_comment = formatmessage(20529)
  14238.  
  14239.  
  14240.     SELECT @publisher_id = publisher_id, @publisher_db = publisher_db, 
  14241.         @publication = publication, @agent_id = id
  14242.         from
  14243.         MSsnapshot_agents 
  14244.         where 
  14245.         name = @name 
  14246.  
  14247.     insert into @latest_session_timestamps 
  14248.         select max(timestamp), count(*)
  14249.           from MSsnapshot_history
  14250.          where (runstatus <> @initializing or
  14251.                 comments <> @start_agent_comment) 
  14252.       group by agent_id, start_time
  14253.         having agent_id = @agent_id
  14254.  
  14255.     /* Get date starting point */
  14256.     IF @hours < 0
  14257.     BEGIN
  14258.         select top 100 sh1.runstatus, 
  14259.             'start_time' = convert(nvarchar(12), sh1.start_time, 112) + 
  14260.                            substring(convert(nvarchar(24), sh1.start_time, 121), 11, 13), 
  14261.             'time' = convert(nvarchar(12), sh1.time, 112) + 
  14262.                      substring(convert(nvarchar(24), sh1.time, 121), 11, 13), 
  14263.             sh1.comments, sh1.duration,
  14264.             sh1.delivery_rate, sh1.delivered_commands,
  14265.             'action_count' = lst.action_count,
  14266.             sh1.error_id
  14267.             from MSsnapshot_history sh1
  14268.             inner join @latest_session_timestamps lst
  14269.             on sh1.timestamp = lst.timestamp
  14270.             where
  14271.             sh1.agent_id = @agent_id and
  14272.             ((@session_type = 1)  or
  14273.             sh1.runstatus = @failure) 
  14274.             order by sh1.timestamp desc
  14275.     END
  14276.     ELSE
  14277.     BEGIN
  14278.         IF @hours = 0
  14279.         BEGIN
  14280.             select @min_time = NULL
  14281.         END
  14282.         ELSE
  14283.         BEGIN
  14284.             select @min_time = dateadd(hour, -@hours, getdate())
  14285.         END
  14286.         select sh1.runstatus, 
  14287.             'start_time' = convert(nvarchar(12), sh1.start_time, 112) + 
  14288.                            substring(convert(nvarchar(24), sh1.start_time, 121), 11, 13), 
  14289.             'time' = convert(nvarchar(12), sh1.time, 112) + 
  14290.                      substring(convert(nvarchar(24), sh1.time, 121), 11, 13), 
  14291.             sh1.comments, sh1.duration,
  14292.             sh1.delivery_rate, sh1.delivered_commands,
  14293.             'action_count' = lst.action_count,
  14294.             sh1.error_id
  14295.             from MSsnapshot_history sh1
  14296.             inner join @latest_session_timestamps lst
  14297.             on sh1.timestamp = lst.timestamp
  14298.             where
  14299.             sh1.agent_id = @agent_id and
  14300.             ((@session_type = 1)  or
  14301.             sh1.runstatus = @failure) and
  14302.             (sh1.time >= @min_time OR @min_time IS NULL)
  14303.             order by sh1.timestamp desc
  14304.     END
  14305.  
  14306. GO
  14307.  
  14308.  
  14309. raiserror(15339,-1,-1,'sp_MSenum_snapshot_sd')
  14310. go
  14311. create procedure sp_MSenum_snapshot_sd
  14312. @name nvarchar(100),
  14313. @time datetime = NULL
  14314. as
  14315.     set nocount on
  14316.  
  14317.     declare @start_time datetime
  14318.     declare @time_up datetime
  14319.     declare @publisher_id smallint
  14320.     declare @publisher_db sysname
  14321.     declare @publication sysname
  14322.  
  14323.     IF @time IS NULL
  14324.         select @time = GETDATE()
  14325.     /* 
  14326.     ** If @name is given, get its publisher and subscriber pair
  14327.     ** Note: param will be overwritten
  14328.     ** If @name is NOT given, use provided param.
  14329.     */
  14330.     SELECT @publisher_id = pub.publisher_id, @publisher_db = pub.publisher_db, 
  14331.         @publication = pub.publication
  14332.         from
  14333.         MSsnapshot_agents agent, MSpublications pub
  14334.         where 
  14335.         name LIKE @name and
  14336.         agent.publisher_id = pub.publisher_id and
  14337.         agent.publication = pub.publication and
  14338.         agent.publisher_db = pub.publisher_db
  14339.     
  14340.     /*
  14341.     ** Minute-approximate @time can be used.
  14342.     **
  14343.     ** Note: The select only return datetime data with minute precisio
  14344.     */
  14345.     IF  DATEPART(second, @time) = 0 AND
  14346.         DATEPART(millisecond, @time) = 0
  14347.     BEGIN
  14348.         SELECT @time_up = DATEADD(second, +59, @time)
  14349.         SELECT @time_up = DATEADD(millisecond, +999, @time)
  14350.     END
  14351.     ELSE
  14352.         SELECT @time_up = @time
  14353.         
  14354.  
  14355.     select top 1 @start_time = sh.start_time            
  14356.          from MSsnapshot_history sh, MSsnapshot_agents sa
  14357.         where
  14358.         sa.publisher_id = @publisher_id and
  14359.         sa.publisher_db = @publisher_db and
  14360.         sa.publication  = @publication and
  14361.         sh.agent_id = sa.id and
  14362.         sh.time <= @time_up 
  14363.         order by sh.timestamp DESC
  14364.  
  14365.     select sh.runstatus, 
  14366.         'time' = convert(nvarchar(12), sh.time, 112) + 
  14367.                  substring(convert(nvarchar(24), sh.time, 121), 11, 13), 
  14368.         sh.comments, 
  14369.         sh.duration, 
  14370.         sh.delivery_rate, 
  14371.         sh.delivered_commands,
  14372.         sa.name, 
  14373.         sh.error_id         
  14374.         from MSsnapshot_history sh, MSsnapshot_agents sa
  14375.         where
  14376.         sa.publisher_id = @publisher_id and
  14377.         sa.publisher_db = @publisher_db and
  14378.         sa.publication = @publication and 
  14379.         sh.agent_id = sa.id and
  14380.         sh.start_time = @start_time 
  14381.         order by sh.timestamp desc
  14382. GO
  14383.  
  14384.  
  14385. raiserror(15339,-1,-1,'sp_MSenum_logreader')
  14386. go
  14387. create procedure sp_MSenum_logreader
  14388. @name nvarchar(100) = '%',
  14389. @show_distdb bit = 0
  14390. as
  14391.     set nocount on
  14392.  
  14393.     declare @publisher sysname
  14394.     declare @publisher_db sysname
  14395.     declare @logreader_agent nvarchar(100)
  14396.     declare @status int
  14397.     declare @start_time nvarchar(24)
  14398.     declare @time nvarchar(24)
  14399.     declare @duration int
  14400.     declare @comments nvarchar(255)
  14401.     declare @delivery_time int
  14402.     declare @delivered_transactions int
  14403.     declare @delivered_commands int
  14404.     declare @average_commands int
  14405.     declare @delivery_rate int
  14406.     declare @delivery_latency int
  14407.     declare @error_id int
  14408.     declare @job_id binary(16)
  14409.     declare @local_job bit
  14410.     declare @profile_id int
  14411.     declare @agent_id int
  14412.     declare @last_timestamp binary(8)
  14413.  
  14414.  
  14415.     create table #logreader_agent (name nvarchar(100) NOT NULL, status int NOT NULL,
  14416.         publisher sysname NOT NULL, publisher_db sysname NOT NULL,
  14417.         start_time nvarchar(24)  NULL, time nvarchar(24)  NULL, duration int  NULL, 
  14418.         comments nvarchar(255) NULL, delivery_time int NULL, 
  14419.         delivered_transactions int  NULL, delivered_commands int NULL, 
  14420.         average_commands int  NULL, delivery_rate int NULL, 
  14421.         delivery_latency int NULL, error_id int NULL, job_id binary(16) NULL,
  14422.         local_job bit NULL, profile_id int NOT NULL, agent_id int NOT NULL, last_timestamp binary(8) NOT NULL)  
  14423.    
  14424.     declare hC  CURSOR LOCAL FAST_FORWARD FOR
  14425.          select server.srvname, agent.publisher_db, name, 
  14426.             local_job, job_id, agent.profile_id, agent.id
  14427.             from
  14428.             MSlogreader_agents agent, master..sysservers server
  14429.             where 
  14430.             name LIKE @name and
  14431.             server.srvid = agent.publisher_id
  14432.         
  14433.         for read only
  14434.  
  14435.     OPEN hC
  14436.     FETCH hC INTO @publisher, @publisher_db, @logreader_agent, 
  14437.         @local_job, @job_id, @profile_id, @agent_id
  14438.     WHILE (@@fetch_status <> -1)
  14439.         begin
  14440.  
  14441.         /* Stuff in the values for no history case */
  14442.         select @status = 0, 
  14443.             @start_time = NULL,
  14444.             @time = NULL, @duration = NULL, @comments = NULL,
  14445.             @delivery_time = NULL, @delivered_transactions = NULL,
  14446.             @delivered_commands = NULL, @average_commands = NULL,
  14447.             @delivery_rate = NULL, @delivery_latency = NULL,
  14448.             @error_id = NULL,
  14449.             @last_timestamp = 0x00000000
  14450.  
  14451.         -- Get the status of the agent
  14452.         select @status = lh.runstatus, 
  14453.             @start_time = convert(nvarchar(12), start_time, 112) +
  14454.                           substring(convert(nvarchar(24), start_time, 121), 11, 13),
  14455.             @time = convert(nvarchar(12), time, 112) +
  14456.                     substring(convert(nvarchar(24),  time, 121), 11, 13), 
  14457.             @duration = duration, 
  14458.             @comments = comments,
  14459.             @delivery_time = delivery_time, @delivered_transactions = delivered_transactions,
  14460.             @delivered_commands = delivered_commands, @average_commands = average_commands,
  14461.             @delivery_rate = delivery_rate, @delivery_latency = delivery_latency,
  14462.             @error_id = error_id, @last_timestamp = timestamp
  14463.             from MSlogreader_history lh
  14464.             where
  14465.             lh.agent_id = @agent_id and
  14466.             lh.timestamp = (select max(timestamp) from MSlogreader_history
  14467.                 where
  14468.                 agent_id = lh.agent_id)
  14469.  
  14470.         insert into #logreader_agent values (@logreader_agent, @status, @publisher,
  14471.             @publisher_db, @start_time, @time, @duration, @comments,
  14472.             @delivery_time, @delivered_transactions, @delivered_commands, @average_commands,
  14473.             @delivery_rate, @delivery_latency, @error_id, @job_id, @local_job,
  14474.             @profile_id, @agent_id, @last_timestamp)
  14475.  
  14476.         FETCH hC INTO @publisher, @publisher_db, @logreader_agent, 
  14477.             @local_job, @job_id, @profile_id, @agent_id
  14478.         end
  14479.  
  14480.     if @show_distdb = 0
  14481.         select * from #logreader_agent 
  14482.     else 
  14483.         select 'dbname' = DB_NAME(), * from #logreader_agent
  14484.  
  14485.     drop table #logreader_agent
  14486.     close hC
  14487.     deallocate hC
  14488. GO
  14489.  
  14490.  
  14491. raiserror(15339,-1,-1,'sp_MSenum_logreader_s')
  14492. go
  14493.  
  14494. create procedure sp_MSenum_logreader_s
  14495. @name nvarchar(100),
  14496. @hours int = 0, /* @hours < 0 will return TOP 100 */
  14497. @session_type int = 1 /* Return all sessions */
  14498. as
  14499.     set nocount on
  14500.  
  14501.     declare @succeed int
  14502.     declare @agent_id int
  14503.     declare @retry int
  14504.     declare @failure int                                 
  14505.     declare @min_time datetime
  14506.  
  14507.     if @session_type  not in (1,2)
  14508.     begin
  14509.         return(1)
  14510.     end 
  14511.  
  14512.     select @agent_id  = (select top 1 id from MSlogreader_agents where name = @name) 
  14513.     /* 
  14514.     ** Status const defined in sqlrepl.h 
  14515.     */
  14516.     select @succeed = 2
  14517.     select @retry = 5
  14518.     select @failure = 6
  14519.  
  14520.     /* Get date starting point */
  14521.     IF @hours < 0
  14522.     BEGIN
  14523.         select top 100 runstatus, 
  14524.                 'start_time' = convert(nvarchar(12), start_time, 112) + 
  14525.                                substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  14526.                 'time' = convert(nvarchar(12), time, 112) +
  14527.                          substring(convert(nvarchar(24), time, 121), 11, 13), 
  14528.                 comments, duration, delivery_rate, delivery_latency,
  14529.             delivery_time,  delivered_transactions, delivered_commands, average_commands, 
  14530.             'action_count' = (select count(*) from MSlogreader_history where
  14531.                 start_time = rh.start_time and agent_id=@agent_id),
  14532.             error_id
  14533.             from MSlogreader_history rh
  14534.             where
  14535.             rh.agent_id = @agent_id and
  14536.             ((@session_type = 1 and (runstatus = @succeed or
  14537.                 runstatus = @retry or
  14538.                 timestamp = (select max(timestamp) from MSlogreader_history rh2 where
  14539.                     rh2.agent_id = rh.agent_id))) or
  14540.             runstatus = @failure) 
  14541.             order by timestamp desc
  14542.     END
  14543.     ELSE
  14544.     BEGIN
  14545.         IF @hours = 0
  14546.         BEGIN
  14547.             select @min_time = NULL
  14548.         END
  14549.         ELSE
  14550.         BEGIN
  14551.             select @min_time = dateadd(hour, -@hours, getdate())
  14552.         END
  14553.         select  runstatus, 
  14554.                 'start_time' = convert(nvarchar(12), start_time, 112) + 
  14555.                                substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  14556.                 'time' = convert(nvarchar(12), time, 112) +
  14557.                          substring(convert(nvarchar(24), time, 121), 11, 13), 
  14558.                 comments, duration, delivery_rate, delivery_latency,
  14559.             delivery_time,  delivered_transactions, delivered_commands, average_commands, 
  14560.             'action_count' = (select count(*) from MSlogreader_history where
  14561.                 start_time = rh.start_time),
  14562.             error_id
  14563.             from MSlogreader_history rh
  14564.             where
  14565.             rh.agent_id = (select top 1 id from MSlogreader_agents where name = @name) and
  14566.             ((@session_type = 1 and (runstatus = @succeed or
  14567.                 runstatus = @retry or
  14568.                 timestamp = (select max(timestamp) from MSlogreader_history rh2 where
  14569.                     rh2.agent_id = rh.agent_id))) or
  14570.             runstatus = @failure) and
  14571.             (time >= @min_time OR @min_time IS NULL)
  14572.             order by timestamp desc
  14573.     END
  14574.  
  14575. GO
  14576.  
  14577. raiserror(15339,-1,-1,'sp_MSenum_logreader_sd')
  14578. go
  14579.  
  14580. create procedure sp_MSenum_logreader_sd
  14581. @name nvarchar(100),
  14582. @time datetime = NULL
  14583. as
  14584.     set nocount on
  14585.  
  14586.     declare @start_time datetime
  14587.     declare @time_up datetime
  14588.  
  14589.     IF @time IS NULL
  14590.         select @time = GETDATE()
  14591.     /*
  14592.     ** Minute-approximate @time can be used.
  14593.     ** Note: The select only return datetime data with minute precision
  14594.     */
  14595.     IF  DATEPART(second, @time) = 0 AND
  14596.         DATEPART(millisecond, @time) = 0
  14597.     BEGIN
  14598.         SELECT @time_up = DATEADD(second, +59, @time)
  14599.         SELECT @time_up = DATEADD(millisecond, +999, @time)
  14600.     END
  14601.     ELSE
  14602.         SELECT @time_up = @time
  14603.         
  14604.  
  14605.     select  top 1 @start_time = start_time          
  14606.          from MSlogreader_history rh
  14607.         where
  14608.         rh.agent_id = (select top 1 id from MSlogreader_agents where name = @name) and
  14609.         time <= @time_up 
  14610.         order by timestamp DESC
  14611.  
  14612.     select  runstatus, 
  14613.             'time' = convert(nvarchar(12), time, 112) +
  14614.                      substring(convert(nvarchar(24), time, 121), 11, 13), 
  14615.             comments,duration, delivery_rate, delivery_latency,
  14616.         delivery_time,  delivered_transactions, delivered_commands, average_commands, 
  14617.         error_id        
  14618.         from MSlogreader_history rh
  14619.         where
  14620.         rh.agent_id = (select top 1 id from MSlogreader_agents where name = @name) and
  14621.         start_time = @start_time 
  14622.         order by timestamp desc
  14623. GO
  14624.  
  14625. raiserror(15339,-1,-1,'sp_MSenum_qreader')
  14626. go
  14627. create procedure sp_MSenum_qreader (
  14628.     @name nvarchar(100) = '%',
  14629.     @show_distdb bit = 0)
  14630. as
  14631. begin
  14632.     set nocount on
  14633.  
  14634.     declare @agent_name nvarchar(100)
  14635.     declare @status int
  14636.     declare @start_time nvarchar(24)
  14637.     declare @time nvarchar(24)
  14638.     declare @duration int
  14639.     declare @comments nvarchar(255)
  14640.     declare @transactions_processed int
  14641.     declare @commands_processed int
  14642.     declare @average_commands int
  14643.     declare @delivery_rate int
  14644.     declare @delivery_latency int
  14645.     declare @error_id int
  14646.     declare @job_id binary(16)
  14647.     declare @agent_id int
  14648.     declare @profile_id int
  14649.     declare @last_timestamp binary(8)
  14650.     declare @first_timestamp binary(8)
  14651.  
  14652.  
  14653.     create table #qreader_agent (name nvarchar(100) NOT NULL, status int NOT NULL,
  14654.         start_time nvarchar(24) NULL, time nvarchar(24) NULL, duration int NULL,
  14655.         comments nvarchar(255) NULL, 
  14656.         transactions_processed int NULL, commands_processed int NULL, 
  14657.         average_commands int NULL, delivery_rate int NULL, delivery_latency int NULL,
  14658.         error_id INT NULL, job_id binary(16) NULL, 
  14659.         profile_id int NULL, agent_id int NOT NULL, local_timestamp binary(8) NOT NULL)
  14660.  
  14661.     declare hC CURSOR LOCAL FAST_FORWARD FOR
  14662.         select id, name, job_id, profile_id
  14663.         from MSqreader_agents 
  14664.         where name = case when ((@name = '%') or (@name is NULL)) then name else @name end
  14665.         for read only
  14666.  
  14667.     OPEN hC
  14668.     FETCH hC INTO @agent_id, @agent_name, @job_id, @profile_id
  14669.     WHILE (@@fetch_status <> -1)
  14670.     begin       
  14671.         --
  14672.         -- Initialize
  14673.         --
  14674.         select @status = 0, 
  14675.             @delivery_latency = 0
  14676.  
  14677.         --
  14678.         -- select the last timestamp
  14679.         --
  14680.         select @last_timestamp = max(timestamp) from MSqreader_history 
  14681.             where agent_id = @agent_id
  14682.  
  14683.         --
  14684.         -- select the last time the agent was started
  14685.         --
  14686.         select @first_timestamp = max(timestamp) from MSqreader_history
  14687.             where agent_id = @agent_id and runstatus = 1
  14688.             
  14689.         --
  14690.         -- Get start time, duration
  14691.         --
  14692.         select @start_time = convert(nvarchar(12), start_time, 112) +
  14693.                             substring(convert(nvarchar(24), start_time, 121), 11, 13)
  14694.         from MSqreader_history
  14695.             where agent_id = @agent_id and timestamp = @first_timestamp
  14696.             
  14697.         --
  14698.         -- Compute the transaction processed, commands processed,
  14699.         -- avg commands, delivery rate
  14700.         --
  14701.         select @transactions_processed = sum(ISNULL(transactions_processed, 0)) 
  14702.                 ,@commands_processed = sum(ISNULL(commands_processed, 0))
  14703.                 ,@average_commands =  avg(ISNULL(commands_processed, 0))
  14704.                 ,@delivery_rate = cast(avg(ISNULL(delivery_rate, 0.0)) as int)
  14705.             from MSqreader_history
  14706.             where agent_id = @agent_id 
  14707.                 and timestamp >= @first_timestamp and timestamp <= @last_timestamp
  14708.                 and transactions_processed > 0
  14709.                 
  14710.         --
  14711.         -- Get the duration, time, status, comments, error from last log
  14712.         --
  14713.         select 
  14714.             @duration = duration,
  14715.             @time = convert(nvarchar(12), time, 112) +
  14716.                             substring(convert(nvarchar(24), time, 121), 11, 13),
  14717.             @status = isnull(runstatus, 0),
  14718.             @comments = comments,
  14719.             @error_id = error_id
  14720.         from MSqreader_history
  14721.         where 
  14722.             agent_id = @agent_id and
  14723.             timestamp = @last_timestamp
  14724.             
  14725.         insert into #qreader_agent values(@agent_name, @status, @start_time, 
  14726.             @time, @duration, @comments, @transactions_processed, @commands_processed, 
  14727.             @average_commands, @delivery_rate, @delivery_latency,
  14728.             @error_id, @job_id, @profile_id, @agent_id, isnull(@last_timestamp,0x00))            
  14729.  
  14730.         FETCH hC INTO @agent_id, @agent_name, @job_id, @profile_id
  14731.     end
  14732.  
  14733.     if @show_distdb = 0
  14734.         select * from #qreader_agent 
  14735.     else 
  14736.         select 'dbname' = DB_NAME(), * from #qreader_agent
  14737.  
  14738.     drop table #qreader_agent
  14739.     close hC
  14740.     deallocate hC
  14741. end
  14742. GO
  14743.  
  14744.  
  14745. raiserror(15339,-1,-1,'sp_MSenum_qreader_s')
  14746. go
  14747. create procedure sp_MSenum_qreader_s (
  14748.     @publication_id int = 0, 
  14749.     @hours int = 0, /* @hours < 0 will return TOP 100 */
  14750.     @session_type int = 1 /* Return all sessions */
  14751. )
  14752. as
  14753. begin
  14754.     set nocount on
  14755.  
  14756.     declare @succeed int
  14757.             ,@retry int
  14758.             ,@failure int
  14759.             ,@min_time datetime
  14760.             ,@agent_id int
  14761.             ,@maxtimestamp timestamp
  14762.             ,@session_start timestamp
  14763.             ,@next_session_start timestamp
  14764.             ,@session_end timestamp
  14765.             ,@final_ts timestamp
  14766.  
  14767.             ,@status int,
  14768.             @start_time nvarchar(24), 
  14769.             @time nvarchar(24), 
  14770.             @comments nvarchar(255), 
  14771.             @duration int, 
  14772.             @delivery_rate int, 
  14773.             @delivery_latency int,
  14774.             @transactions_processed int, 
  14775.             @commands_processed int, 
  14776.             @average_commands int, 
  14777.             @action_count int, 
  14778.             @error_id int,
  14779.             @start_datetime datetime,
  14780.             @end_datetime datetime
  14781.     
  14782.     if @session_type  not in (1,2)
  14783.     begin
  14784.         return(1)
  14785.     end
  14786.     
  14787.     /* 
  14788.     ** Status const defined in sqlrepl.h 
  14789.     */
  14790.     select @succeed = 2
  14791.     select @retry = 5
  14792.     select @failure = 6
  14793.  
  14794.     -- create the table to store sessions
  14795.     create table #qreader_session (status int NOT NULL,
  14796.         start_time nvarchar(24) NOT NULL, time nvarchar(24) NOT NULL, comments nvarchar(255) NULL, 
  14797.         duration int NULL, delivery_rate int NULL, delivery_latency int NULL,
  14798.         publication_id int NULL, transactions_processed int NULL, commands_processed int NULL, 
  14799.         average_commands int NULL, action_count int NULL, error_id INT NULL, local_timestamp binary(8) NOT NULL)
  14800.         
  14801.     -- get the agent id
  14802.     select TOP 1 @agent_id = agent_id from MSqreader_history 
  14803.  
  14804.     --
  14805.     -- If Min time specified, initilialize it
  14806.     --
  14807.     IF (@hours < 1)
  14808.         select @min_time = NULL
  14809.     ELSE
  14810.         select @min_time = dateadd(hour, -@hours, getdate())
  14811.  
  14812.     -- initialize
  14813.     select @delivery_latency = 0
  14814.             ,@next_session_start = NULL
  14815.             ,@session_end = NULL
  14816.             ,@final_ts = max(timestamp) 
  14817.     from MSqreader_history
  14818.     
  14819.     -- Get the session details
  14820.     while (@session_end != @final_ts)
  14821.     begin
  14822.         --
  14823.         -- Mark the beginning of a new session
  14824.         --
  14825.         if (@next_session_start is NULL)
  14826.         begin
  14827.             select @session_start = min(timestamp) from MSqreader_history
  14828.                 where agent_id = @agent_id and runstatus = 1
  14829.         end
  14830.         else
  14831.         begin
  14832.             select @session_start = @next_session_start 
  14833.         end
  14834.  
  14835.         --
  14836.         -- update @next_session_start
  14837.         --
  14838.         select @next_session_start = ISNULL(min(timestamp), @final_ts) 
  14839.         from MSqreader_history
  14840.         where agent_id = @agent_id and timestamp > @session_start and runstatus = 1
  14841.  
  14842.         --
  14843.         -- find session end based on @next_session_start
  14844.         --
  14845.         if (@next_session_start = @final_ts)
  14846.             select @session_end = @final_ts
  14847.         else
  14848.         begin
  14849.             select @session_end = max(timestamp)
  14850.             from MSqreader_history
  14851.             where agent_id = @agent_id and
  14852.                 timestamp > @session_start and 
  14853.                 timestamp < @next_session_start
  14854.         end
  14855.         
  14856.         --
  14857.         -- get start time for this session
  14858.         --
  14859.         select @start_datetime = start_time, 
  14860.             @start_time = convert(nvarchar(12), start_time, 112) +
  14861.                         substring(convert(nvarchar(24), start_time, 121), 11, 13)
  14862.         from MSqreader_history                        
  14863.         where agent_id = @agent_id and timestamp = @session_start                        
  14864.  
  14865.         --
  14866.         -- do we need to process this session 
  14867.         --
  14868.         if (@start_time IS NULL)
  14869.         begin
  14870.             --
  14871.             -- Check if we are done with all sessions
  14872.             --
  14873.             if (@session_end = @final_ts)
  14874.                 break
  14875.             else
  14876.                 continue
  14877.         end
  14878.  
  14879.         --
  14880.         -- get status, end time, comments, error id for this session
  14881.         --
  14882.         select @status = runstatus,
  14883.             @end_datetime = time,
  14884.             @time = convert(nvarchar(12), time, 112) +
  14885.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  14886.             @comments = comments, 
  14887.             @error_id = ISNULL(error_id, 0) 
  14888.         from MSqreader_history                        
  14889.         where agent_id = @agent_id and timestamp = @session_end                        
  14890.  
  14891.         --
  14892.         -- do we need to continue this session - min time check
  14893.         --
  14894.         if ((@min_time is NOT NULL) and (@min_time > @end_datetime))
  14895.         begin
  14896.             --
  14897.             -- Check if we are done with all sessions
  14898.             --
  14899.             if (@session_end = @final_ts)
  14900.                 break
  14901.             else
  14902.                 continue
  14903.         end
  14904.  
  14905.         --
  14906.         -- get duration, action count, tran processed, cmds processed, avg cmds, etc
  14907.         -- for this session
  14908.         --
  14909.         select @duration = DATEDIFF(second, @start_datetime, @end_datetime)
  14910.         select @action_count = ISNULL(count(*), 0)
  14911.             from MSqreader_history
  14912.             where agent_id = @agent_id 
  14913.                 and timestamp >= @session_start and timestamp <= @session_end
  14914.  
  14915.         select @transactions_processed = sum(ISNULL(transactions_processed, 0)) 
  14916.                 ,@commands_processed = sum(ISNULL(commands_processed, 0))
  14917.                 ,@average_commands =  avg(ISNULL(commands_processed, 0))
  14918.                 ,@delivery_rate = cast(avg(ISNULL(delivery_rate, 0.0)) as int)
  14919.             from MSqreader_history
  14920.             where agent_id = @agent_id 
  14921.                 and timestamp >= @session_start and timestamp <= @session_end
  14922.                 and transactions_processed > 0
  14923.  
  14924.         --
  14925.         -- insert into #qreader_session
  14926.         --
  14927.         insert into    #qreader_session values(@status, @start_time, @time, @comments, 
  14928.             @duration, @delivery_rate, @delivery_latency, NULL, @transactions_processed, 
  14929.             @commands_processed, @average_commands, @action_count, @error_id, @session_end)
  14930.  
  14931.         --
  14932.         -- Check if we are done with all sessions
  14933.         --
  14934.         if (@session_end = @final_ts)
  14935.             break
  14936.     end
  14937.  
  14938.     -- return results
  14939.     
  14940.     if (@hours < 0)
  14941.         select top 100 
  14942.             status,
  14943.             start_time,
  14944.             time, 
  14945.             comments, 
  14946.             duration,
  14947.             delivery_rate,
  14948.             delivery_latency,
  14949.             publication_id,
  14950.             transactions_processed, 
  14951.             commands_processed, 
  14952.             average_commands, 
  14953.             action_count, 
  14954.             error_id
  14955.         from #qreader_session
  14956.         where (@session_type = 2 and (status = @failure)) or 
  14957.                 (@session_type = 1)
  14958.         order by local_timestamp desc
  14959.     else
  14960.         select 
  14961.             status,
  14962.             start_time,
  14963.             time, 
  14964.             comments, 
  14965.             duration,
  14966.             delivery_rate,
  14967.             delivery_latency,
  14968.             publication_id,
  14969.             transactions_processed, 
  14970.             commands_processed, 
  14971.             average_commands, 
  14972.             action_count, 
  14973.             error_id
  14974.         from #qreader_session        
  14975.         where (@session_type = 2 and (status = @failure)) or 
  14976.                 (@session_type = 1)
  14977.         order by local_timestamp desc
  14978. end
  14979. GO
  14980.  
  14981.  
  14982. raiserror(15339,-1,-1,'sp_MSenum_qreader_sd')
  14983. go
  14984. create procedure sp_MSenum_qreader_sd (
  14985.     @publication_id int = 0, 
  14986.     @time datetime = NULL)
  14987. as
  14988. begin
  14989.     set nocount on
  14990.  
  14991.     declare @time_up datetime
  14992.             ,@agent_id int
  14993.             ,@final_ts timestamp
  14994.             ,@initial_ts timestamp
  14995.             ,@session_start timestamp
  14996.             ,@next_session_start timestamp
  14997.             ,@session_end timestamp
  14998.  
  14999.     if (@publication_id = 0)
  15000.         select @publication_id = NULL
  15001.         
  15002.     IF @time IS NULL
  15003.         select @time = GETDATE()
  15004.  
  15005.     /*
  15006.     ** Minute-approximate @time can be used.
  15007.     ** Note: The select only return datetime data with minute precision
  15008.     */
  15009.     IF ( (DATEPART(second, @time) = 0) AND
  15010.             (DATEPART(millisecond, @time) = 0) )
  15011.     BEGIN
  15012.         SELECT @time_up = DATEADD(second, +59, @time)
  15013.         SELECT @time_up = DATEADD(millisecond, +999, @time)
  15014.     END
  15015.     ELSE
  15016.         SELECT @time_up = @time
  15017.  
  15018.     --
  15019.     -- Get the agent id
  15020.     --
  15021.     select TOP 1 @agent_id = agent_id from MSqreader_history 
  15022.  
  15023.     --
  15024.     -- Get the session start, next session start timestamps
  15025.     --
  15026.     select @initial_ts = min(timestamp), @final_ts = max(timestamp) from MSqreader_history
  15027.     
  15028.     select @session_start = ISNULL(max(timestamp), @initial_ts) from MSqreader_history
  15029.             where agent_id = @agent_id and time <= @time_up and runstatus = 1
  15030.             
  15031.     select @next_session_start = ISNULL(min(timestamp), @final_ts) from MSqreader_history
  15032.             where agent_id = @agent_id and timestamp > @session_start and runstatus = 1
  15033.  
  15034.     --
  15035.     -- find session end based on @next_session_start
  15036.     --
  15037.     if (@next_session_start = @final_ts)
  15038.         select @session_end = @final_ts
  15039.     else
  15040.     begin
  15041.         select @session_end = max(timestamp)
  15042.         from MSqreader_history
  15043.         where agent_id = @agent_id and
  15044.             timestamp > @session_start and 
  15045.             timestamp < @next_session_start
  15046.     end
  15047.     
  15048.     --
  15049.     -- Do the select now
  15050.     --
  15051.     select  runstatus, 
  15052.         'time' = convert(nvarchar(12), time, 112) +
  15053.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  15054.         comments, 
  15055.         transaction_id, 
  15056.         transaction_status,
  15057.         commands_processed,
  15058.         subscriber,
  15059.         subscriberdb,
  15060.         'error_id' = ISNULL(error_id, 0)
  15061.     from MSqreader_history
  15062.     where
  15063.         agent_id = @agent_id and
  15064.         timestamp >= @session_start and
  15065.         timestamp <= @session_end
  15066.     order by timestamp desc
  15067. end
  15068. GO
  15069.  
  15070. raiserror(15339,-1,-1,'sp_MSenum_distribution')
  15071. go
  15072. create procedure sp_MSenum_distribution
  15073. @name nvarchar(100) = '%',
  15074. @show_distdb bit = 0,
  15075. @exclude_anonymous bit = 0
  15076. as
  15077.     set nocount on
  15078.  
  15079.     declare @publisher sysname
  15080.     declare @publisher_id smallint
  15081.     declare @publisher_db sysname
  15082.     declare @publication sysname
  15083.     declare @subscriber sysname
  15084.     declare @subscriber_id smallint
  15085.     declare @subscriber_db sysname
  15086.     declare @subscriber_name sysname
  15087.     declare @distribution_agent nvarchar(100)
  15088.     declare @status int
  15089.     declare @start_time nvarchar(24)
  15090.     declare @time nvarchar(24)
  15091.     declare @duration int
  15092.     declare @comments nvarchar(255)
  15093.     declare @delivery_time int
  15094.     declare @delivered_transactions int
  15095.     declare @delivered_commands int
  15096.     declare @average_commands int
  15097.     declare @delivery_rate int
  15098.     declare @delivery_latency int   
  15099.     declare @subscription_type int
  15100.     declare @error_id int
  15101.     declare @job_id binary(16)
  15102.     declare @local_job bit
  15103.     declare @agent_id int
  15104.     declare @profile_id int
  15105.     declare @last_timestamp binary(8)
  15106.     declare @offload_enabled bit
  15107.     declare @offload_server  sysname
  15108.         ,@subscriber_type tinyint
  15109.  
  15110.  
  15111.     create table #distribution_agent (name nvarchar(100) NOT NULL, status int NOT NULL,
  15112.         publisher sysname NOT NULL, publisher_db sysname NOT NULL, publication sysname NULL,
  15113.         subscriber sysname NULL, subscriber_db sysname NULL,subscription_type int NULL, 
  15114.         start_time nvarchar(24) NULL, time nvarchar(24) NULL, duration int NULL, 
  15115.         comments nvarchar(255) NULL, delivery_time int NULL, 
  15116.         delivered_transactions int NULL, delivered_commands int NULL, 
  15117.         average_commands int NULL, delivery_rate int NULL, delivery_latency int NULL,
  15118.         error_id int NULL, job_id binary(16) NULL, local_job bit NOT NULL,
  15119.         profile_id int NOT NULL, agent_id int NOT NULL, last_timestamp binary(8) NOT NULL, 
  15120.         offload_enabled BIT NOT NULL, offload_server sysname NULL,
  15121.         subscriber_type tinyint NULL)
  15122.  
  15123.     /* excluding virtual subscriptions */
  15124.     declare hC CURSOR LOCAL FAST_FORWARD FOR
  15125.         select id, name, publisher_id, publisher_db, publication, 
  15126.             subscriber_id, subscriber_db, subscription_type, local_job, job_id,
  15127.             profile_id, subscriber_name, offload_enabled, offload_server
  15128.             from
  15129.             MSdistribution_agents 
  15130.             where 
  15131.             --No virtual subscription wanted
  15132.             name LIKE @name and (subscriber_id is NULL or subscriber_id>=0) and
  15133.             (@exclude_anonymous = 0 or anonymous_agent_id is null)
  15134.         for read only
  15135.  
  15136.  
  15137.     OPEN hC
  15138.     FETCH hC INTO @agent_id, @distribution_agent, @publisher_id, @publisher_db, @publication,
  15139.         @subscriber_id, @subscriber_db, @subscription_type, @local_job, @job_id, @profile_id, @subscriber_name, @offload_enabled, @offload_server
  15140.     WHILE (@@fetch_status <> -1)
  15141.         begin
  15142.         
  15143.         /* Stuff in the values for no history case */
  15144.         select @status = 0, 
  15145.             @start_time = NULL,
  15146.             @time = NULL, @duration = NULL, @comments = NULL,
  15147.             @delivery_time = NULL, @delivered_transactions = NULL,
  15148.             @delivered_commands = NULL, @average_commands = NULL,
  15149.             @delivery_rate = NULL, @delivery_latency = NULL,
  15150.             @error_id = NULL,
  15151.             @last_timestamp = 0x00000000
  15152.  
  15153.         select @status = isnull(runstatus, 0),
  15154.             @start_time = convert(nvarchar(12), start_time, 112) +
  15155.                           substring(convert(nvarchar(24), start_time, 121), 11, 13),
  15156.             @time = convert(nvarchar(12), time, 112) +
  15157.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  15158.             @duration = duration, 
  15159.             @comments = comments,
  15160.             @delivery_time = 0, @delivered_transactions = delivered_transactions,
  15161.             @delivered_commands = delivered_commands, @average_commands = average_commands,
  15162.             @delivery_rate = delivery_rate,
  15163.             @delivery_latency = delivery_latency,
  15164.             @error_id = error_id, @last_timestamp = timestamp   
  15165.             from MSdistribution_history
  15166.             where
  15167.             agent_id = @agent_id and
  15168.             timestamp = (select max(timestamp) from MSdistribution_history 
  15169.                 where agent_id = @agent_id)
  15170.             
  15171.             select @publisher = srvname from master..sysservers where srvid = @publisher_id
  15172.         IF @subscriber_name is NULL
  15173.         begin
  15174.                 select @subscriber = srvname from master..sysservers where srvid=@subscriber_id 
  15175.                 select @subscriber_type = type from MSsubscriber_info where
  15176.                     UPPER(publisher) = UPPER(@publisher) and
  15177.                     UPPER(subscriber) = UPPER(@subscriber)
  15178.  
  15179.         end
  15180.         ELSE 
  15181.             begin
  15182.                 select @subscription_type = 2
  15183.                 select @subscriber = @subscriber_name
  15184.                 select @subscriber_db = @subscriber_db + '-' + convert(nvarchar(4), @agent_id)
  15185.             end
  15186.             
  15187.         insert into #distribution_agent values (@distribution_agent,
  15188.             @status, @publisher,
  15189.             @publisher_db, @publication, @subscriber, @subscriber_db, @subscription_type, 
  15190.             @start_time, @time, @duration, @comments,
  15191.             @delivery_time, @delivered_transactions, @delivered_commands, @average_commands,
  15192.             @delivery_rate, @delivery_latency, @error_id, @job_id, 
  15193.             @local_job, @profile_id, @agent_id, @last_timestamp, @offload_enabled, 
  15194.             @offload_server, @subscriber_type)
  15195.  
  15196.         FETCH hC INTO @agent_id, @distribution_agent, @publisher_id, @publisher_db, @publication,
  15197.             @subscriber_id, @subscriber_db, @subscription_type, @local_job, @job_id, 
  15198.             @profile_id, @subscriber_name, @offload_enabled, @offload_server
  15199.         end
  15200.  
  15201.     if @show_distdb = 0
  15202.         select * from #distribution_agent 
  15203.     else 
  15204.         select 'dbname' = DB_NAME(), * from #distribution_agent
  15205.  
  15206.     drop table #distribution_agent
  15207.     close hC
  15208.     deallocate hC
  15209.  
  15210. GO
  15211.  
  15212.  
  15213. raiserror(15339,-1,-1,'sp_MSenum_distribution_s')
  15214. go
  15215. create procedure sp_MSenum_distribution_s
  15216. @name nvarchar(100), 
  15217. @hours int = 0, /* @hours < 0 will return TOP 100 */
  15218. @session_type int = 1 /* Return all sessions */
  15219. as
  15220.     set nocount on
  15221.  
  15222.     declare @succeed int
  15223.     declare @retry int
  15224.     declare @failure int
  15225.     declare @min_time datetime
  15226.     declare @agent_id int
  15227.  
  15228.     /* 
  15229.     ** Status const defined in sqlrepl.h 
  15230.     */
  15231.     select @succeed = 2
  15232.     select @retry = 5
  15233.     select @failure = 6
  15234.  
  15235.     select @agent_id = id from MSdistribution_agents where
  15236.         name = @name
  15237.  
  15238.  
  15239.     /* Get date starting point */
  15240.     IF @hours < 0
  15241.     BEGIN
  15242.         select top 100 runstatus, 
  15243.             'start_time' = convert(nvarchar(12), start_time, 112) +
  15244.                            substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  15245.             'time' = convert(nvarchar(12), time, 112) +
  15246.                      substring(convert(nvarchar(24), time, 121), 11, 13), 
  15247.             comments, duration, 
  15248.             delivery_rate,
  15249.             delivery_latency,
  15250.             0, /*delivery_time */   
  15251.             delivered_transactions, delivered_commands, average_commands, 
  15252.             'action_count' = (select count(*) from MSdistribution_history where
  15253.                 start_time = rh.start_time and agent_id = @agent_id),
  15254.             error_id
  15255.             from MSdistribution_history rh
  15256.             where
  15257.             agent_id = @agent_id and
  15258.             ((@session_type = 1 and
  15259.             (runstatus = @succeed or
  15260.             runstatus = @retry or
  15261.             timestamp = (select max(timestamp) from MSdistribution_history rh2 where
  15262.                 rh2.agent_id = @agent_id))) or 
  15263.             runstatus = @failure)
  15264.             order by timestamp desc
  15265.     END
  15266.     ELSE
  15267.     BEGIN
  15268.         IF @hours = 0
  15269.         BEGIN
  15270.             select @min_time = NULL
  15271.         END
  15272.         ELSE
  15273.         BEGIN
  15274.             select @min_time = dateadd(hour, -@hours, getdate())
  15275.         END
  15276.         select  runstatus, 
  15277.             'start_time' = convert(nvarchar(12), start_time, 112) +
  15278.                            substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  15279.             'time' = convert(nvarchar(12), time, 112) +
  15280.                      substring(convert(nvarchar(24), time, 121), 11, 13), 
  15281.             comments, duration, 
  15282.             delivery_rate,
  15283.             delivery_latency,
  15284.             0, /*delivery_time */   
  15285.             delivered_transactions, delivered_commands, average_commands, 
  15286.             'action_count' = (select count(*) from MSdistribution_history where
  15287.                 start_time = rh.start_time and agent_id = @agent_id),
  15288.             error_id
  15289.             from MSdistribution_history rh
  15290.             where
  15291.             agent_id = @agent_id and
  15292.             ((@session_type = 1 and
  15293.             (runstatus = @succeed or
  15294.             runstatus = @retry or
  15295.             timestamp = (select max(timestamp) from MSdistribution_history rh2 where
  15296.                 rh2.agent_id = @agent_id))) or 
  15297.             runstatus = @failure) and
  15298.             (time >= @min_time or @min_time IS NULL)
  15299.             order by timestamp desc
  15300.     END
  15301.  
  15302. GO
  15303.  
  15304.  
  15305. raiserror(15339,-1,-1,'sp_MSenum_distribution_sd')
  15306. go
  15307. create procedure sp_MSenum_distribution_sd
  15308. @name nvarchar(100),
  15309. @time datetime = NULL
  15310. as
  15311.     set nocount on
  15312.  
  15313.     declare @start_time datetime
  15314.     declare @time_up datetime
  15315.     declare @agent_id int
  15316.  
  15317.     IF @time IS NULL
  15318.         select @time = GETDATE()
  15319.     
  15320.     select @agent_id = id from MSdistribution_agents where
  15321.         name = @name
  15322.  
  15323.     /*
  15324.     ** Minute-approximate @time can be used.
  15325.     ** Note: The select only return datetime data with minute precision
  15326.     */
  15327.     IF  DATEPART(second, @time) = 0 AND
  15328.         DATEPART(millisecond, @time) = 0
  15329.     BEGIN
  15330.         SELECT @time_up = DATEADD(second, +59, @time)
  15331.         SELECT @time_up = DATEADD(millisecond, +999, @time)
  15332.     END
  15333.     ELSE
  15334.         SELECT @time_up = @time
  15335.         
  15336.  
  15337.     select top 1 @start_time = start_time           
  15338.          from MSdistribution_history rh
  15339.         where
  15340.         rh.agent_id = @agent_id and
  15341.         time <= @time_up
  15342.         order by timestamp DESC
  15343.  
  15344.     select  runstatus, 
  15345.         'time' = convert(nvarchar(12), time, 112) +
  15346.                  substring(convert(nvarchar(24), time, 121), 11, 13), 
  15347.         comments, duration, 
  15348.         delivery_rate,
  15349.         delivery_latency,
  15350.         /* delivery_time */ 0,  
  15351.         delivered_transactions, delivered_commands, average_commands, 
  15352.         error_id            
  15353.         from MSdistribution_history rh
  15354.         where
  15355.         rh.agent_id = @agent_id and
  15356.         start_time = @start_time
  15357.         order by timestamp desc
  15358. GO
  15359.  
  15360.  
  15361. raiserror(15339,-1,-1,'sp_MSadd_merge_history')
  15362. go
  15363. CREATE PROCEDURE sp_MSadd_merge_history (
  15364.     @agent_id       int,        
  15365.     @runstatus      int, 
  15366.     @comments       nvarchar(255),
  15367.     @delivery_time  int = 0,                    /* Milliseconds */
  15368.     @publisher_insertcount  int = 0,
  15369.     @publisher_updatecount  int = 0,
  15370.     @publisher_deletecount  int = 0,
  15371.     @publisher_conflictcount int = 0,
  15372.     @subscriber_insertcount int = 0,
  15373.     @subscriber_updatecount int = 0,
  15374.     @subscriber_deletecount int = 0,
  15375.     @subscriber_conflictcount int = 0,
  15376.     @log_error bit = 0,
  15377.     @perfmon_increment bit = 1,
  15378.     @update_existing_row bit = 0,
  15379.     @updateable_row bit = 1,     -- used to override history verbose level to decide
  15380.                     -- whether the row being added can be updated by another.    
  15381.     @do_raiserror bit = 1
  15382. )
  15383. AS
  15384. BEGIN
  15385.  
  15386.     DECLARE @current_time datetime
  15387.             ,@start_time datetime
  15388.             ,@duration int
  15389.             ,@delivery_rate float
  15390.             ,@perfmon_delivery_rate int
  15391.             ,@perfmon_conflict_count int
  15392.             ,@delivered_rows int
  15393.             ,@changes int
  15394.             ,@delivery_time_old  int
  15395.             ,@delivered_rows_old int
  15396.             ,@publisher_insertcount_old  int 
  15397.             ,@publisher_updatecount_old  int 
  15398.             ,@publisher_deletecount_old  int 
  15399.             ,@publisher_conflictcount_old int 
  15400.             ,@subscriber_insertcount_old int 
  15401.             ,@subscriber_updatecount_old int 
  15402.             ,@subscriber_deletecount_old int 
  15403.             ,@subscriber_conflictcount_old int 
  15404.             ,@publisher_id smallint
  15405.             ,@subscriber_id smallint
  15406.             ,@error_id int 
  15407.             ,@startup int
  15408.             ,@succeed int
  15409.             ,@retry int
  15410.             ,@inprogress int
  15411.             ,@failure int
  15412.             ,@idle int
  15413.             ,@lastrow_timestamp timestamp
  15414.             ,@agent_name nvarchar(100)
  15415.             ,@publisher sysname
  15416.             ,@publisher_db sysname
  15417.             ,@publication sysname
  15418.             ,@retcode int
  15419.             ,@existing_row_updateble bit
  15420.             ,@this_row_updateable bit
  15421.             ,@agentclassname sysname
  15422.             ,@lastrunstatus int
  15423.  
  15424.     /* 
  15425.     ** Status const defined in sqlrepl.h 
  15426.     */
  15427.     select @startup = 1
  15428.             ,@succeed = 2
  15429.             ,@inprogress = 3
  15430.             ,@idle = 4
  15431.             ,@retry = 5
  15432.             ,@failure = 6
  15433.             ,@delivery_time_old  = 0
  15434.             ,@publisher_insertcount_old   = 0
  15435.             ,@publisher_updatecount_old   = 0
  15436.             ,@publisher_deletecount_old   = 0
  15437.             ,@publisher_conflictcount_old  = 0
  15438.             ,@subscriber_insertcount_old  = 0
  15439.             ,@subscriber_updatecount_old  = 0
  15440.             ,@subscriber_deletecount_old  = 0
  15441.             ,@subscriber_conflictcount_old  = 0
  15442.             ,@existing_row_updateble = 1
  15443.             ,@this_row_updateable = 1
  15444.  
  15445.     if (@updateable_row = 0)
  15446.     begin
  15447.         select @this_row_updateable = 0
  15448.     end
  15449.  
  15450.     if sessionproperty('replication_agent') = 0
  15451.     begin
  15452.         -- Security Check
  15453.         exec @retcode = dbo.sp_MScheck_pull_access
  15454.             @agent_id = @agent_id,
  15455.             @agent_type = 1 -- merge agent
  15456.         if @@error <> 0 or @retcode <> 0
  15457.             return (1)
  15458.     end
  15459.  
  15460.     SELECT @current_time = GETDATE()
  15461.  
  15462.     -- Update Perfmon counter
  15463.     if @perfmon_increment = 1
  15464.     begin
  15465.         if @runstatus = @startup
  15466.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Merge", 1)
  15467.         else if (@runstatus = @succeed or @runstatus = @retry or @runstatus = @failure)
  15468.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Merge", -1)
  15469.     end
  15470.  
  15471.     SELECT @agent_name = name, @publisher_id = publisher_id, @publisher_db = publisher_db, 
  15472.         @publication = publication from MSmerge_agents where id = @agent_id
  15473.     SELECT @publisher = srvname from master..sysservers where srvid = @publisher_id
  15474.  
  15475.     IF @runstatus = @inprogress or @runstatus = @idle
  15476.         BEGIN
  15477.             SELECT TOP 1 @start_time = start_time, 
  15478.                     @lastrow_timestamp = timestamp,
  15479.                     @publisher_insertcount_old = publisher_insertcount ,
  15480.                     @publisher_updatecount_old = publisher_updatecount, 
  15481.                     @publisher_deletecount_old = publisher_deletecount,
  15482.                     @publisher_conflictcount_old = publisher_conflictcount,
  15483.                     @subscriber_insertcount_old = subscriber_insertcount, 
  15484.                     @subscriber_updatecount_old = subscriber_updatecount,
  15485.                     @subscriber_deletecount_old = subscriber_deletecount,
  15486.                     @subscriber_conflictcount_old = subscriber_conflictcount,
  15487.                     @delivery_time_old = delivery_time,
  15488.                     @existing_row_updateble = updateable_row
  15489.             FROM MSmerge_history (rowlock)
  15490.             WHERE  agent_id = @agent_id ORDER BY timestamp DESC
  15491.         
  15492.             select @delivered_rows_old = @publisher_insertcount_old + 
  15493.                              @publisher_updatecount_old +
  15494.                              @publisher_deletecount_old +
  15495.                              @subscriber_updatecount_old +
  15496.                              @subscriber_insertcount_old +
  15497.                              @subscriber_deletecount_old 
  15498.         END
  15499.     ELSE IF @runstatus <> 1 --1 is the Start status
  15500.         BEGIN
  15501.             SELECT TOP 1 @start_time = start_time, 
  15502.                         @lastrow_timestamp = timestamp,
  15503.                         @lastrunstatus = runstatus
  15504.             FROM MSmerge_history (rowlock)
  15505.             WHERE  agent_id = @agent_id ORDER BY timestamp DESC
  15506.  
  15507.             if (@lastrunstatus = @succeed or @lastrunstatus = @failure or @lastrunstatus = @retry)
  15508.             begin
  15509.                 select @start_time = @current_time
  15510.             end
  15511.         END
  15512.     ELSE
  15513.         BEGIN
  15514.             SELECT @start_time = @current_time
  15515.         END
  15516.  
  15517.     /* Use the current time if no corresponding start_up message logged */
  15518.     IF @start_time IS NULL
  15519.        SELECT @start_time = @current_time
  15520.  
  15521.     /* Calculate agent run duration */
  15522.     SELECT @duration = DATEDIFF(second, @start_time, @current_time) 
  15523.  
  15524.     if (@start_time = @current_time and (@runstatus = @succeed or @runstatus = @failure or @runstatus = @retry))
  15525.     begin
  15526.         declare @logintime datetime
  15527.         select @logintime = NULL
  15528.  
  15529.         select @logintime = (select top 1 login_time from master.dbo.sysprocesses (NOLOCK) where spid = @@spid)
  15530.  
  15531.         set @start_time = @logintime
  15532.         if (@logintime is not null)
  15533.         begin
  15534.             select @duration = DATEDIFF(second, @logintime, @current_time)
  15535.         end
  15536.     end
  15537.                              
  15538.     select @delivered_rows = @publisher_insertcount + 
  15539.                              @publisher_updatecount +
  15540.                              @publisher_deletecount +
  15541.                              @subscriber_updatecount +
  15542.                              @subscriber_insertcount +
  15543.                              @subscriber_deletecount 
  15544.  
  15545.     -- Set Perfmon counters
  15546.     if @runstatus = @idle or @runstatus = @inprogress
  15547.     begin
  15548.         dbcc addinstance ("SQL Replication Merge", @agent_name)
  15549.  
  15550.         set @changes = @publisher_insertcount + @publisher_updatecount + @publisher_deletecount                             
  15551.         dbcc incrementinstance ("SQL Replication Merge", "Downloaded Changes", @agent_name, @changes)
  15552.  
  15553.         set @changes = @subscriber_updatecount + @subscriber_insertcount + @subscriber_deletecount 
  15554.         dbcc incrementinstance ("SQL Replication Merge", "Uploaded Changes", @agent_name, @changes)
  15555.  
  15556.         set @perfmon_conflict_count = @publisher_conflictcount + @subscriber_conflictcount
  15557.         dbcc incrementinstance ("SQL Replication Merge", "Conflicts", @agent_name, @perfmon_conflict_count)
  15558.     end
  15559.  
  15560.     if @runstatus = @inprogress  or @runstatus = @idle            -- if it is in progress, then do incremental change
  15561.     begin
  15562.         select @publisher_insertcount = @publisher_insertcount_old + @publisher_insertcount
  15563.         select      @publisher_updatecount = @publisher_updatecount_old + @publisher_updatecount
  15564.         select      @publisher_deletecount = @publisher_deletecount_old + @publisher_deletecount
  15565.         select      @publisher_conflictcount = @publisher_conflictcount_old + @publisher_conflictcount
  15566.         select      @subscriber_insertcount = @subscriber_insertcount_old + @subscriber_insertcount
  15567.         select     @subscriber_updatecount = @subscriber_updatecount_old + @subscriber_updatecount
  15568.         select     @subscriber_deletecount = @subscriber_deletecount_old + @subscriber_deletecount
  15569.         select     @subscriber_conflictcount = @subscriber_conflictcount_old + @subscriber_conflictcount
  15570.  
  15571.         select  @delivery_time = @delivery_time_old + @delivery_time
  15572.         select @delivered_rows = @delivered_rows + @delivered_rows_old
  15573.     end
  15574.     
  15575.     IF @duration <> 0 
  15576.        SELECT @delivery_rate = (@delivered_rows * 1.0) / @duration
  15577.     ELSE
  15578.        SELECT @delivery_rate = 0
  15579.  
  15580.     /* 
  15581.     ** Set error id to 0 unless the user want to log errors associate with this 
  15582.     ** history message.
  15583.     */
  15584.     SELECT @error_id = 0
  15585.     IF @log_error = 1
  15586.     BEGIN
  15587.         -- Ignore errors here. @error_id will be set to 0 in case of errors  
  15588.         EXEC dbo.sp_MSget_new_errorid @error_id OUTPUT
  15589.     END
  15590.  
  15591.     -- Insert idle record or update if history record is already 'idle'
  15592.     IF (@existing_row_updateble = 1) and (@runstatus = @idle or @update_existing_row = 1)
  15593.     begin
  15594.         -- Attempt to update the last row if it is IDLE
  15595.         UPDATE MSmerge_history SET runstatus = @runstatus, time = @current_time, duration = @duration,
  15596.             comments = @comments,
  15597.             delivery_time = @delivery_time, 
  15598.             delivery_rate = @delivery_rate, 
  15599.             publisher_insertcount = @publisher_insertcount,
  15600.             publisher_updatecount = @publisher_updatecount,
  15601.             publisher_deletecount = @publisher_deletecount,
  15602.             publisher_conflictcount = @publisher_conflictcount,
  15603.             subscriber_insertcount = @subscriber_insertcount,
  15604.             subscriber_updatecount = @subscriber_updatecount,
  15605.             subscriber_deletecount = @subscriber_deletecount,
  15606.             subscriber_conflictcount = @subscriber_conflictcount,
  15607.             updateable_row = @this_row_updateable,
  15608.             error_id = case @error_id when 0 then error_id else @error_id end    
  15609.             WHERE
  15610.             agent_id = @agent_id and
  15611.             timestamp = @lastrow_timestamp and
  15612.             (runstatus = @runstatus or 
  15613.             (@update_existing_row = 1 and runstatus in (@idle, @inprogress) and @runstatus in (@idle, @inprogress)))
  15614.  
  15615.         -- Insert idle record if there is not one
  15616.         if @@ROWCOUNT = 0
  15617.             INSERT INTO MSmerge_history
  15618.             (
  15619.             agent_id, runstatus, start_time, time, duration, comments, delivery_time, delivery_rate, publisher_insertcount,
  15620.             publisher_updatecount, publisher_deletecount, publisher_conflictcount, subscriber_insertcount, subscriber_updatecount,
  15621.             subscriber_deletecount, subscriber_conflictcount, error_id, timestamp, updateable_row
  15622.             )
  15623.             VALUES 
  15624.             (
  15625.             @agent_id, @runstatus, @start_time, @current_time, 
  15626.             @duration, @comments,  @delivery_time, @delivery_rate, 
  15627.             @publisher_insertcount, @publisher_updatecount, @publisher_deletecount, @publisher_conflictcount, 
  15628.             @subscriber_insertcount, @subscriber_updatecount, @subscriber_deletecount, @subscriber_conflictcount, 
  15629.             @error_id, NULL, @this_row_updateable
  15630.             )
  15631.     end
  15632.     else
  15633.     begin
  15634.         INSERT INTO MSmerge_history 
  15635.         (
  15636.             agent_id, runstatus, start_time, time, duration, comments, delivery_time, delivery_rate, publisher_insertcount,
  15637.             publisher_updatecount, publisher_deletecount, publisher_conflictcount, subscriber_insertcount, subscriber_updatecount,
  15638.             subscriber_deletecount, subscriber_conflictcount, error_id, timestamp, updateable_row
  15639.         )
  15640.         VALUES 
  15641.         (
  15642.         @agent_id, @runstatus, @start_time, @current_time, 
  15643.         @duration, @comments, @delivery_time, @delivery_rate, 
  15644.         @publisher_insertcount, @publisher_updatecount, @publisher_deletecount, @publisher_conflictcount, 
  15645.         @subscriber_insertcount, @subscriber_updatecount, @subscriber_deletecount, @subscriber_conflictcount, 
  15646.         @error_id, NULL, @this_row_updateable
  15647.         )
  15648.     end
  15649.  
  15650.     -- Refresh repl monitor
  15651.     declare @agent_type int
  15652.     set @agent_type = dbo.fn_MSmask_agent_type (@agent_id, 4)
  15653.  
  15654.     -- Update global replication agent status table
  15655.     exec dbo.sp_MSupdate_replication_status 
  15656.         @publisher, 
  15657.         @publisher_db,
  15658.         @publication,
  15659.         @publication_type = 2,
  15660.         @agent_type = @agent_type,
  15661.         @agent_name = @agent_name,
  15662.         @status = @runstatus
  15663.  
  15664.     -- Raise the appropriate error
  15665.     if @do_raiserror = 1
  15666.     begin
  15667.         select @agentclassname = formatmessage(14554)
  15668.         exec dbo.sp_MSrepl_raiserror agentclassname, @agent_name, @runstatus, @comments
  15669.     end
  15670.  
  15671.     IF @@ERROR <> 0
  15672.         RETURN (1)
  15673.  
  15674.     RETURN (0)
  15675. END
  15676. GO   
  15677.  
  15678. raiserror(15339,-1,-1,'sp_MSenum_merge')
  15679. go
  15680. create procedure sp_MSenum_merge
  15681. @name nvarchar(100) = '%',
  15682. @show_distdb bit = 0,
  15683. @exclude_anonymous bit = 0
  15684. as
  15685.     set nocount on
  15686.  
  15687.     declare @publisher sysname
  15688.     declare @publisher_id smallint
  15689.     declare @publisher_db sysname
  15690.     declare @subscriber sysname
  15691.     declare @subscriber_id smallint
  15692.     declare @subscriber_db sysname
  15693.     declare @subscriber_name sysname
  15694.     declare @subscription_type int
  15695.     declare @publication sysname
  15696.     declare @status int
  15697.     declare @start_time nvarchar(24)
  15698.     declare @time nvarchar(24)
  15699.     declare @duration int
  15700.     declare @comments nvarchar(255)
  15701.     declare @publisher_insertcount int
  15702.     declare @publisher_updatecount int
  15703.     declare @publisher_deletecount int
  15704.     declare @publisher_conflictcount int
  15705.     declare @subscriber_insertcount int
  15706.     declare @subscriber_updatecount int
  15707.     declare @subscriber_deletecount int
  15708.     declare @subscriber_conflictcount int
  15709.     declare @delivery_rate int
  15710.     declare @agent_name nvarchar(100)
  15711.     declare @error_id int
  15712.     declare @job_id binary(16)
  15713.     declare @local_job bit
  15714.     declare @profile_id int
  15715.     declare @agent_id int
  15716.     declare @last_timestamp binary(8)
  15717.     declare @offload_enabled bit
  15718.     declare @offload_server  sysname
  15719.         ,@subscriber_type tinyint
  15720.  
  15721.  
  15722.     create table #merge_agent (name nvarchar(100) NOT NULL, status int NOT NULL,
  15723.         publisher sysname NOT NULL, publisher_db sysname NOT NULL, publication sysname NULL,
  15724.         subscriber sysname NOT NULL, subscriber_db sysname NOT NULL, subscription_type int NULL,
  15725.         start_time nvarchar(24) NULL, time nvarchar(24) NULL, duration int NULL, 
  15726.         comments nvarchar(255) NULL, delivery_rate int NULL,
  15727.         publisher_insertcount int NULL, publisher_updatecount int NULL, publisher_deletecount int NULL,
  15728.         publisher_conficts int NULL, 
  15729.         subscriber_insertcount int NULL, subscriber_updatecount int NULL, subscriber_deletecount int NULL,
  15730.         subscriber_conficts int NULL, error_id int NULL, job_id binary(16) NULL,
  15731.         local_job bit NULL, profile_id int NOT NULL, agent_id int NOT NULL, last_timestamp binary(8) NOT NULL,
  15732.         offload_enabled bit NOT NULL, offload_server sysname NULL,
  15733.         subscriber_type tinyint NULL)
  15734.  
  15735.     declare hC CURSOR LOCAL FAST_FORWARD FOR
  15736.         select p.publisher_id, a.subscriber_id, a.publisher_db, a.subscriber_db, 
  15737.             p.publication, a.name, a.local_job, a.job_id, a.profile_id, a.id, a.subscriber_name, 
  15738.             offload_enabled, offload_server
  15739.             from MSmerge_agents a, MSpublications p
  15740.             where 
  15741.             a.name LIKE @name and
  15742.             a.publisher_id = p.publisher_id and
  15743.             a.publisher_db = p.publisher_db and
  15744.             a.publication = p.publication and
  15745.             (@exclude_anonymous = 0 or a.subscriber_name is null)
  15746.  
  15747.         for read only
  15748.  
  15749.  
  15750.     OPEN hC
  15751.     FETCH hC INTO @publisher_id, @subscriber_id, @publisher_db, @subscriber_db,
  15752.         @publication, @agent_name, @local_job, @job_id, @profile_id, @agent_id, @subscriber_name, 
  15753.         @offload_enabled, @offload_server
  15754.  
  15755.     WHILE (@@fetch_status <> -1)
  15756.     begin
  15757.  
  15758.         /* Initialize the values for no history case */
  15759.         select @status = 0,
  15760.             @start_time = NULL,
  15761.             @time = NULL, 
  15762.             @duration = NULL, 
  15763.             @comments = NULL,
  15764.             @publisher_insertcount = 0,
  15765.             @publisher_deletecount = 0,
  15766.             @publisher_updatecount = 0,
  15767.             @publisher_conflictcount = 0,
  15768.             @subscriber_insertcount = 0,
  15769.             @subscriber_deletecount = 0,
  15770.             @subscriber_updatecount = 0,
  15771.             @subscriber_conflictcount = 0,
  15772.             @delivery_rate = 0,
  15773.             @error_id = NULL, 
  15774.             @last_timestamp = 0x00000000
  15775.  
  15776.         select @status = isnull(runstatus,0),
  15777.             @start_time = convert(nvarchar(12), start_time, 112) +
  15778.                           substring(convert(nvarchar(24), start_time, 121), 11, 13),
  15779.             @time = convert(nvarchar(12), time, 112) +
  15780.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  15781.             @duration = duration, 
  15782.             @comments = comments,
  15783.             @publisher_insertcount = publisher_insertcount,
  15784.             @publisher_deletecount = publisher_deletecount,
  15785.             @publisher_updatecount =  publisher_updatecount,
  15786.             @publisher_conflictcount =  publisher_conflictcount,
  15787.             @subscriber_insertcount = subscriber_insertcount,
  15788.             @subscriber_deletecount = subscriber_deletecount,
  15789.             @subscriber_updatecount =  subscriber_updatecount,
  15790.             @subscriber_conflictcount =  subscriber_conflictcount,
  15791.             -- Note: return average rate here !!! delivery_rate column is current rate
  15792.             @delivery_rate = 
  15793.                 case    when duration <> 0 then 
  15794.                             (publisher_insertcount + publisher_updatecount +
  15795.                             publisher_deletecount + subscriber_insertcount + 
  15796.                             subscriber_updatecount + subscriber_deletecount)/duration
  15797.                         when duration = 0 then 0
  15798.                 end, 
  15799.             @error_id = error_id, @last_timestamp = timestamp
  15800.             from MSmerge_history
  15801.             where
  15802.                 agent_id = @agent_id and
  15803.                 timestamp = (select max(timestamp) from MSmerge_history mh2
  15804.                     where mh2.agent_id = @agent_id)
  15805.  
  15806.         select @publisher = srvname from master..sysservers where srvid = @publisher_id
  15807.  
  15808.         -- For non anonymous agents, @subscriber_name is null 
  15809.         if @subscriber_name is NULL
  15810.             begin
  15811.                 select @subscriber = srvname from master..sysservers where srvid = @subscriber_id
  15812.                 if @local_job = 1 select @subscription_type = 0
  15813.                     else select @subscription_type = 1
  15814.                 select @subscriber_type = type from MSsubscriber_info where
  15815.                     UPPER(publisher) = UPPER(@publisher) and
  15816.                     UPPER(subscriber) = UPPER(@subscriber)
  15817.             end
  15818.         else 
  15819.             begin
  15820.                 select @subscriber = @subscriber_name
  15821.                 select @subscriber_db = @subscriber_db + '-' +  convert(nvarchar(4), @agent_id)
  15822.                 select @subscription_type = 2   -- anonymous type
  15823.             end
  15824.         
  15825.         insert into #merge_agent values (@agent_name, @status, @publisher,
  15826.             @publisher_db, @publication, @subscriber, @subscriber_db, @subscription_type,
  15827.             @start_time, @time, @duration, @comments, @delivery_rate,
  15828.             @publisher_insertcount, @publisher_updatecount, @publisher_deletecount, 
  15829.             @publisher_conflictcount,
  15830.             @subscriber_insertcount, @subscriber_updatecount, @subscriber_deletecount, 
  15831.             @subscriber_conflictcount,
  15832.             @error_id, @job_id, @local_job, @profile_id, @agent_id, @last_timestamp,
  15833.             @offload_enabled, @offload_server, @subscriber_type)
  15834.  
  15835.         FETCH hC INTO @publisher_id, @subscriber_id, @publisher_db, @subscriber_db,
  15836.             @publication, @agent_name, @local_job, @job_id, @profile_id,
  15837.             @agent_id, @subscriber_name, @offload_enabled, @offload_server
  15838.         end
  15839.  
  15840.     if @show_distdb = 0
  15841.         select * from #merge_agent 
  15842.     else 
  15843.         select 'dbname' = DB_NAME(), * from #merge_agent
  15844.  
  15845.     drop table #merge_agent
  15846.     close hC
  15847.     deallocate hC
  15848.  
  15849. GO
  15850.  
  15851.  
  15852. raiserror(15339,-1,-1,'sp_MSenum_merge_s')
  15853. go
  15854.  
  15855. create procedure sp_MSenum_merge_s
  15856. @name nvarchar(100), 
  15857. @hours int = 0, /* @hours < 0 will return TOP 100 */
  15858. @session_type int = 1 /* Return all sessions */
  15859. as
  15860.     set nocount on
  15861.  
  15862.     declare @succeed int
  15863.     declare @agent_id int
  15864.     declare @retry int
  15865.     declare @failure int
  15866.     declare @min_time datetime
  15867.  
  15868.     /* 
  15869.     ** Status const defined in sqlrepl.h 
  15870.     */
  15871.     select @succeed = 2
  15872.     select @retry = 5
  15873.     select @failure = 6
  15874.  
  15875.     select @agent_id = id from MSmerge_agents where name = @name
  15876.  
  15877.     /* Get date starting point */
  15878.     IF @hours < 0
  15879.     BEGIN
  15880.         select top 100 runstatus, 
  15881.             'start_time' = convert(nvarchar(12), start_time, 112) +
  15882.                            substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  15883.             'time' = convert(nvarchar(12), time, 112) +
  15884.                      substring(convert(nvarchar(24), time, 121), 11, 13), 
  15885.             comments, duration, 
  15886.             -- Note: return average rate here !!! delivery_rate column is current rate
  15887.             case    when duration <> 0 then 
  15888.                             (publisher_insertcount + publisher_updatecount +
  15889.                             publisher_deletecount + subscriber_insertcount + 
  15890.                             subscriber_updatecount + subscriber_deletecount)/duration
  15891.                     when duration = 0 then 0
  15892.             end, 
  15893.             publisher_insertcount, publisher_updatecount, publisher_deletecount, publisher_conflictcount,
  15894.             subscriber_insertcount, subscriber_updatecount, subscriber_deletecount, subscriber_conflictcount,
  15895.             'action_count' = (select count(*) from MSmerge_history where
  15896.                 start_time = rh.start_time and agent_id = @agent_id),
  15897.             error_id
  15898.             from MSmerge_history rh
  15899.             where
  15900.             agent_id = @agent_id and
  15901.             ((@session_type = 1 and
  15902.             (runstatus = @succeed or
  15903.             runstatus = @retry or
  15904.             timestamp = (select max(timestamp) from MSmerge_history rh2 where
  15905.                 rh2.agent_id = @agent_id))) or 
  15906.             runstatus = @failure)
  15907.             order by timestamp desc
  15908.     END
  15909.     ELSE
  15910.     BEGIN
  15911.         IF @hours = 0
  15912.         BEGIN
  15913.             select @min_time = NULL
  15914.         END
  15915.         ELSE
  15916.         BEGIN
  15917.             select @min_time = dateadd(hour, -@hours, getdate())
  15918.         END
  15919.         select  runstatus, 
  15920.             'start_time' = convert(nvarchar(12), start_time, 112) +
  15921.                            substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  15922.             'time' = convert(nvarchar(12), time, 112) +
  15923.                      substring(convert(nvarchar(24), time, 121), 11, 13), 
  15924.             comments, duration, 
  15925.             -- Note: return average rate here !!! delivery_rate column is current rate
  15926.             case    when duration <> 0 then 
  15927.                             (publisher_insertcount + publisher_updatecount +
  15928.                             publisher_deletecount + subscriber_insertcount + 
  15929.                             subscriber_updatecount + subscriber_deletecount)/duration
  15930.                     when duration = 0 then 0
  15931.             end, 
  15932.             publisher_insertcount, publisher_updatecount, publisher_deletecount, publisher_conflictcount,
  15933.             subscriber_insertcount, subscriber_updatecount, subscriber_deletecount, subscriber_conflictcount,
  15934.             'action_count' = (select count(*) from MSmerge_history where
  15935.                 start_time = rh.start_time and agent_id = @agent_id),
  15936.             error_id
  15937.             from MSmerge_history rh
  15938.             where
  15939.             agent_id = @agent_id and
  15940.             ((@session_type = 1 and
  15941.             (runstatus = @succeed or
  15942.             runstatus = @retry or
  15943.             timestamp = (select max(timestamp) from MSmerge_history rh2 where
  15944.                 rh2.agent_id = @agent_id))) or 
  15945.             runstatus = @failure) and
  15946.             (time >= @min_time or @min_time IS NULL)
  15947.             order by timestamp desc
  15948.     END
  15949.  
  15950. GO
  15951.  
  15952. raiserror(15339,-1,-1,'sp_MSenum_merge_sd')
  15953. go
  15954.  
  15955. create procedure sp_MSenum_merge_sd
  15956. @name nvarchar(100),
  15957. @time datetime = NULL
  15958. as
  15959.     set nocount on
  15960.  
  15961.     declare @start_time datetime
  15962.     declare @agent_id int
  15963.     declare @time_up datetime
  15964.  
  15965.     select @agent_id = id from MSmerge_agents where name=@name
  15966.     
  15967.     IF @time IS NULL
  15968.         select @time = GETDATE()
  15969.  
  15970.     /*
  15971.     ** Minute-approximate @time can be used.
  15972.     ** Note: The select only return datetime data with minute precision
  15973.     */
  15974.     IF  DATEPART(second, @time) = 0 AND
  15975.         DATEPART(millisecond, @time) = 0
  15976.     BEGIN
  15977.         SELECT @time_up = DATEADD(second, +59, @time)
  15978.         SELECT @time_up = DATEADD(millisecond, +999, @time)
  15979.     END
  15980.     ELSE
  15981.         SELECT @time_up = @time
  15982.         
  15983.  
  15984.     select top 1 @start_time = start_time           
  15985.          from MSmerge_history rh
  15986.         where
  15987.         rh.agent_id = @agent_id and
  15988.         time <= @time_up
  15989.         order by timestamp DESC
  15990.  
  15991.     select  runstatus, 
  15992.             'time' = convert(nvarchar(12), time, 112) + 
  15993.                      substring(convert(nvarchar(24), time, 121), 11, 13),
  15994.             comments, duration, 
  15995.         -- Note: return average rate here !!! delivery_rate column is current rate
  15996.         case    when duration <> 0 then 
  15997.                         (publisher_insertcount + publisher_updatecount +
  15998.                         publisher_deletecount + subscriber_insertcount + 
  15999.                         subscriber_updatecount + subscriber_deletecount)/duration
  16000.                 when duration = 0 then 0
  16001.         end, 
  16002.         publisher_insertcount, publisher_updatecount, publisher_deletecount, publisher_conflictcount,
  16003.         subscriber_insertcount, subscriber_updatecount, subscriber_deletecount, subscriber_conflictcount,
  16004.         error_id            
  16005.         from MSmerge_history rh
  16006.         where
  16007.         rh.agent_id = @agent_id and
  16008.         start_time = @start_time
  16009.         order by timestamp desc
  16010. GO
  16011.  
  16012. raiserror(15339,-1,-1,'sp_MSenableagentoffload')
  16013. GO
  16014. CREATE PROCEDURE sp_MSenableagentoffload (
  16015.     @job_id             VARBINARY(16),
  16016.     @offloadserver      sysname = NULL
  16017.     ) AS
  16018.  
  16019.     SET NOCOUNT ON
  16020.  
  16021.     /*
  16022.     **  Declarations
  16023.     */
  16024.  
  16025.     DECLARE @agent_id          INT
  16026.     DECLARE @subscription_type INT
  16027.     DECLARE @agenttype         NVARCHAR(20)
  16028.     DECLARE @agent_table       sysname 
  16029.     DECLARE @offloadserverwasnull INT
  16030.     DECLARE @retcode           INT
  16031.     
  16032.     SELECT @agent_id = NULL
  16033.     SELECT @subscription_type = 0
  16034.     SELECT @agenttype = NULL    
  16035.     SELECT @agent_table = RTRIM(@@SERVERNAME) + '.' + db_name() + N'.dbo.'
  16036.  
  16037.     -- get the agent type from sysjobsteps table (subsystem) 
  16038.     SELECT @agenttype = LOWER(subsystem collate SQL_Latin1_General_CP1_CS_AS) 
  16039.       FROM msdb..sysjobsteps 
  16040.      WHERE job_id = @job_id
  16041.        AND LOWER(subsystem collate SQL_Latin1_General_CP1_CS_AS) IN (N'distribution', N'merge') 
  16042.     
  16043.     -- validate the agent type, it has to be non null
  16044.     IF @agenttype IS NULL
  16045.     BEGIN
  16046.         RAISERROR(21134, 16, -1)
  16047.         RETURN 1
  16048.     END
  16049.  
  16050.     -- Make sure that the given offload server does not contain
  16051.     -- invalid characters
  16052.     EXEC @retcode = sp_MSreplcheckoffloadserver @offloadserver
  16053.     IF @retcode <> 0 OR @@error <> 0
  16054.     BEGIN
  16055.         RETURN (1)
  16056.     END
  16057.  
  16058.     -- validate the existence of the job_id in the agent table and get 
  16059.     -- the value of the subscription type and agentid at the same time
  16060.     IF @agenttype = N'distribution'
  16061.     BEGIN
  16062.         SELECT @subscription_type = subscription_type,
  16063.                @agent_id = id  
  16064.           FROM dbo.MSdistribution_agents
  16065.          WHERE job_id = @job_id
  16066.         SELECT @agent_table = @agent_table + 'MSdistribution_agents'
  16067.     END
  16068.     ELSE 
  16069.     BEGIN
  16070.         SELECT @subscription_type = ms.subscription_type,
  16071.                @agent_id = ma.id
  16072.           FROM dbo.MSmerge_agents ma 
  16073.     INNER JOIN dbo.MSpublications mp 
  16074.             ON (ma.publisher_id = mp.publisher_id) 
  16075.            AND (ma.publisher_db = mp.publisher_db) 
  16076.            AND (ma.publication = mp.publication)
  16077.     INNER JOIN dbo.MSmerge_subscriptions ms
  16078.             ON (ma.publisher_id = ms.publisher_id)
  16079.            AND (ma.publisher_db = ms.publisher_db)
  16080.            AND (mp.publication_id = ms.publication_id)
  16081.            AND (ma.subscriber_id = ms.subscriber_id)
  16082.            AND (ma.subscriber_db = ms.subscriber_db)
  16083.      WHERE @job_id = ma.job_id
  16084.         SELECT @agent_table = @agent_table + 'MSmerge_agents'
  16085.     END
  16086.  
  16087.     IF @agent_id IS NULL
  16088.     BEGIN
  16089.         RAISERROR(21135, 16, -1, @agent_table)
  16090.         RETURN 1
  16091.     END 
  16092.     ELSE IF @@ROWCOUNT > 1
  16093.     BEGIN
  16094.         RAISERROR(21136, 16, -1, @agent_table)
  16095.         RETURN 1
  16096.     END
  16097.  
  16098.     -- raise error if subscription type is not push
  16099.     IF @subscription_type <> 0
  16100.     BEGIN
  16101.         RAISERROR(21137, 16, -1)
  16102.         RETURN 1
  16103.     END
  16104.  
  16105.     -- raise error if offload server name is the same as the
  16106.     -- distributor's name
  16107.     IF LOWER(@@SERVERNAME) = LOWER(@offloadserver)
  16108.     BEGIN
  16109.         RAISERROR(21138, 16, -1)
  16110.         RETURN 1
  16111.     END
  16112.  
  16113.     -- if the offload server name is NULL, try to obtain the offload server
  16114.     -- name from the agent table
  16115.     IF (@offloadserver IS NULL) OR (@offloadserver = N'')
  16116.     BEGIN
  16117.         SELECT @offloadserverwasnull = 1
  16118.         IF LOWER(@agenttype collate SQL_Latin1_General_CP1_CS_AS) = N'distribution'
  16119.         BEGIN
  16120.             SELECT @offloadserver = offload_server 
  16121.               FROM dbo.MSdistribution_agents
  16122.              WHERE id = @agent_id
  16123.         END
  16124.         ELSE
  16125.         BEGIN
  16126.             SELECT @offloadserver = offload_server
  16127.               FROM dbo.MSmerge_agents
  16128.              WHERE id = @agent_id
  16129.         END
  16130.     END 
  16131.     ELSE
  16132.     BEGIN
  16133.         SELECT @offloadserverwasnull = 0
  16134.     END
  16135.  
  16136.     -- if offload server name is still NULL, use the subscriber as the target 
  16137.     -- server
  16138.     IF (@offloadserver IS NULL) OR (@offloadserver = N'')
  16139.     BEGIN
  16140.         IF LOWER(@agenttype collate SQL_Latin1_General_CP1_CS_AS) = N'distribution'
  16141.         BEGIN
  16142.             SELECT @offloadserver = ss.srvname 
  16143.               FROM master.dbo.sysservers ss 
  16144.         INNER JOIN dbo.MSdistribution_agents da 
  16145.                 ON ss.srvid = da.subscriber_id
  16146.              WHERE @agent_id = da.id
  16147.         END
  16148.         ELSE
  16149.         BEGIN
  16150.             SELECT @offloadserver = ss.srvname
  16151.               FROM master.dbo.sysservers ss 
  16152.         INNER JOIN dbo.MSmerge_agents ma
  16153.                 ON ss.srvid = ma.subscriber_id
  16154.              WHERE @agent_id = ma.id
  16155.         END
  16156.     END
  16157.  
  16158.     IF (@offloadserver IS NULL) OR (@offloadserver = N'') 
  16159.     BEGIN
  16160.         RAISERROR(21139, 16, -1)
  16161.         RETURN 1
  16162.     END
  16163.     ELSE IF LOWER(@offloadserver) = LOWER(@@SERVERNAME) 
  16164.     BEGIN
  16165.         IF @offloadserverwasnull = 1
  16166.         BEGIN
  16167.             RAISERROR(21261, 16, -1)
  16168.         END
  16169.         ELSE
  16170.         BEGIN
  16171.             RAISERROR(21140, 16, -1)
  16172.         END
  16173.         RETURN 1
  16174.     END
  16175.  
  16176.     BEGIN TRANSACTION enable_offload
  16177.     
  16178.     -- Update the agent table with the new offload settings
  16179.     IF LOWER(@agenttype collate SQL_Latin1_General_CP1_CS_AS) = N'distribution'
  16180.     BEGIN
  16181.         UPDATE MSdistribution_agents
  16182.            SET offload_enabled = 1,
  16183.                offload_server = @offloadserver
  16184.          WHERE id = @agent_id
  16185.         IF @@ERROR <> 0
  16186.             GOTO Failure
  16187.     END
  16188.     ELSE
  16189.     BEGIN
  16190.         UPDATE MSmerge_agents
  16191.            SET offload_enabled = 1,
  16192.                offload_server = @offloadserver
  16193.          WHERE id = @agent_id
  16194.         IF @@ERROR <> 0
  16195.             GOTO Failure
  16196.     END    
  16197.  
  16198.     -- Add the offload parameter
  16199.     EXEC sp_MSaddoffloadparameter @offloadserver = @offloadserver,
  16200.                                   @job_id = @job_id,
  16201.                                   @agenttype = @agenttype
  16202.     
  16203.     IF @@ERROR <> 0
  16204.         GOTO Failure
  16205.     COMMIT TRANSACTION enable_offload
  16206.     RETURN 0
  16207. Failure:
  16208.     ROLLBACK TRANSACTION enable_offload
  16209.     RETURN 1
  16210. GO
  16211.  
  16212. raiserror(15339,-1,-1,'sp_MSdisableagentoffload')
  16213. GO
  16214. CREATE PROCEDURE sp_MSdisableagentoffload (
  16215.     @job_id         VARBINARY(16),
  16216.     @offloadserver  sysname = NULL
  16217.     ) AS
  16218.     
  16219.     SET NOCOUNT ON
  16220.     
  16221.     DECLARE @agent_id    INT
  16222.     DECLARE @agenttype   NVARCHAR(20)
  16223.  
  16224.     SELECT @agent_id = NULL
  16225.     SELECT @agenttype = NULL
  16226.  
  16227.     -- Obtain the agent type from the sysjobssteps table
  16228.     SELECT @agenttype = LOWER(subsystem collate SQL_Latin1_General_CP1_CS_AS) 
  16229.       FROM msdb..sysjobsteps
  16230.      WHERE job_id = @job_id
  16231.        AND LOWER(subsystem collate SQL_Latin1_General_CP1_CS_AS) IN (N'merge', N'distribution')
  16232.  
  16233.     -- validate the agent type, it has to be either 'merge' or 'distribution'
  16234.     IF @agenttype IS NULL
  16235.     BEGIN
  16236.         RAISERROR(21134, 16, -1)
  16237.         RETURN 1
  16238.     END
  16239.  
  16240.     -- don't check the subscription type 
  16241.     BEGIN TRANSACTION disable_offload
  16242.     
  16243.     -- Update the agent table with the new offload settings
  16244.     IF @agenttype = N'distribution'
  16245.     BEGIN
  16246.         IF @offloadserver IS NULL -- Leave the existing offload server alone
  16247.         BEGIN
  16248.             UPDATE MSdistribution_agents
  16249.                SET offload_enabled = 0
  16250.              WHERE job_id = @job_id
  16251.             IF @@ERROR <> 0
  16252.                 GOTO Failure
  16253.         END
  16254.         ELSE
  16255.         BEGIN
  16256.             UPDATE MSdistribution_agents
  16257.                SET offload_enabled = 0,
  16258.                    offload_server = @offloadserver
  16259.              WHERE job_id = @job_id            
  16260.             IF @@ERROR <> 0
  16261.                 GOTO Failure
  16262.         END    
  16263.  
  16264.  
  16265.     END
  16266.     ELSE
  16267.     BEGIN
  16268.         IF @offloadserver IS NULL -- Leave the existing offload server alone
  16269.         BEGIN
  16270.             UPDATE MSmerge_agents
  16271.                SET offload_enabled = 0
  16272.              WHERE job_id = @job_id
  16273.             IF @@ERROR <> 0
  16274.                 GOTO Failure
  16275.         END
  16276.         ELSE
  16277.         BEGIN
  16278.             UPDATE MSmerge_agents
  16279.                SET offload_enabled = 0,
  16280.                    offload_server = @offloadserver
  16281.              WHERE job_id = @job_id
  16282.             IF @@ERROR <> 0
  16283.                 GOTO Failure
  16284.         END
  16285.     END    
  16286.  
  16287.     -- Call stored procedure to remove -offload parameter from the 
  16288.     -- agent command line
  16289.  
  16290.     EXEC sp_MSremoveoffloadparameter @job_id = @job_id, 
  16291.                                      @agenttype = @agenttype
  16292.     IF @@ERROR <> 0
  16293.         GOTO Failure
  16294.     COMMIT TRANSACTION disable_offload
  16295.  
  16296.     RETURN 0
  16297. Failure:
  16298.  
  16299.     ROLLBACK TRANSACTION disable_offload
  16300.     RETURN (1)
  16301.  
  16302. GO
  16303.     
  16304. raiserror(15339,-1,-1,'sp_MSadd_repl_error')
  16305. GO
  16306.  
  16307. CREATE PROCEDURE sp_MSadd_repl_error (
  16308. @id                 int,
  16309. @error_type_id      int,
  16310. @source_type_id     int,
  16311. @source_name        sysname,
  16312. @error_code         sysname,
  16313. @error_text         ntext
  16314. )
  16315. AS
  16316.     declare @retcode int
  16317.     declare @xact_seqno varbinary(16)
  16318.     declare @command_id int
  16319.  
  16320.     -- Security Check
  16321.     -- require the login to be in cache regardless of the publication id and agent_id.
  16322.     -- This means that once a agent get into the distribution db, it
  16323.     -- can add any error.   
  16324.     exec @retcode = dbo.sp_MScheck_pull_access
  16325.     if @@error <> 0 or @retcode <> 0
  16326.         return (1)
  16327.  
  16328.     select @xact_seqno = xact_seqno, @command_id = command_id from MSrepl_errors where
  16329.         id = @id and xact_seqno is not null
  16330.     
  16331.     INSERT INTO MSrepl_errors VALUES (@id, getdate(), @error_type_id, @source_type_id,
  16332.         @source_name, @error_code, @error_text, @xact_seqno, @command_id)
  16333.  
  16334.     IF @@ERROR <> 0
  16335.     BEGIN
  16336.        RETURN (1)
  16337.     END
  16338.  
  16339.     return (0)
  16340. GO   
  16341.  
  16342.  
  16343. raiserror(15339,-1,-1,'sp_MSadd_repl_alert')
  16344. GO
  16345.  
  16346. CREATE PROCEDURE sp_MSadd_repl_alert (
  16347. @agent_type         int,
  16348. @agent_id           int,
  16349. @error_id           int,
  16350. @alert_error_code   int,
  16351. @xact_seqno         varbinary(16),      
  16352. @command_id         int,
  16353. @publisher          sysname,
  16354. @publisher_db       sysname,
  16355. @subscriber         sysname,
  16356. @subscriber_db      sysname,
  16357. @alert_error_text   ntext
  16358. )
  16359. AS
  16360.     SET NOCOUNT ON
  16361.  
  16362.     declare @retcode int
  16363.     declare @article sysname
  16364.     declare @article_id int
  16365.     declare @destination_object sysname
  16366.     declare @source_object sysname
  16367.     declare @publisher_id int
  16368.     declare @publication sysname
  16369.     declare @publication_id int
  16370.     declare @publication_type int
  16371.     declare @subscriber_id int
  16372.     declare @publisher_database_id int
  16373.     declare @agent_type2 int
  16374.  
  16375.     -- Security Check
  16376.     if @agent_type = 3
  16377.         select @agent_type2 = 0 -- distribution
  16378.     else if @agent_type = 4
  16379.         select @agent_type2 = 1 -- merge
  16380.  
  16381.     if @agent_type2 is not null 
  16382.     begin
  16383.         exec @retcode = dbo.sp_MScheck_pull_access
  16384.                 @agent_id = @agent_id,
  16385.                 @agent_type = @agent_type2
  16386.         if @@error <> 0 or @retcode <> 0
  16387.             return (1)
  16388.     end
  16389.     else
  16390.     begin
  16391.         if is_member('db_owner') = 0
  16392.         begin
  16393.             RAISERROR (14126, 16, -1)
  16394.             return(1)
  16395.         end
  16396.     end
  16397.  
  16398.     select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  16399.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  16400.     
  16401.     select @publisher_database_id = id from MSpublisher_databases 
  16402.     where publisher_id = @publisher_id and publisher_db = @publisher_db
  16403.  
  16404.     select @article_id = article_id from MSrepl_commands
  16405.     where publisher_database_id = @publisher_database_id
  16406.     and xact_seqno = @xact_seqno
  16407.     and command_id = @command_id
  16408.  
  16409.     select @publication = mp.publication, @publication_id = mp.publication_id, @publication_type = mp.publication_type
  16410.     from MSpublications as mp, MSsubscriptions as ms
  16411.     where mp.publisher_id = ms.publisher_id
  16412.     and mp.publisher_db = ms.publisher_db
  16413.     and mp.publication_id = ms.publication_id
  16414.     and ms.publisher_id = @publisher_id
  16415.     and ms.publisher_db = @publisher_db
  16416.     and ms.subscriber_id = @subscriber_id
  16417.     and ms.subscriber_db = @subscriber_db
  16418.     and ms.article_id = @article_id
  16419.  
  16420.     select @article = article, @destination_object = destination_object, @source_object = source_object 
  16421.     from MSarticles
  16422.     where article_id = @article_id
  16423.         and publisher_id = @publisher_id
  16424.         and publisher_db = @publisher_db
  16425.         and publication_id = @publication_id
  16426.  
  16427.      INSERT INTO msdb.dbo.sysreplicationalerts (status, agent_type , agent_id, error_id, alert_error_code, time, publisher,
  16428.                                 publisher_db, publication, publication_type, subscriber, subscriber_db,
  16429.                                 article, destination_object, source_object, alert_error_text)
  16430.                 VALUES (0, @agent_type, @agent_id, @error_id, @alert_error_code, getdate(), @publisher, 
  16431.                         @publisher_db, @publication, @publication_type, @subscriber, @subscriber_db, 
  16432.                         @article, @destination_object, @source_object, @alert_error_text)
  16433.     
  16434.     IF @@ERROR <> 0
  16435.     BEGIN
  16436.        RETURN (1)
  16437.     END
  16438.  
  16439.     return (0)
  16440. GO   
  16441.  
  16442. raiserror(15339,-1,-1,'sp_MSadd_replmergealert')
  16443. GO
  16444.  
  16445. CREATE PROCEDURE sp_MSadd_replmergealert (
  16446. @agent_type         int,
  16447. @agent_id           int,
  16448. @error_id           int,
  16449. @alert_error_code   int,
  16450. @publisher          sysname,
  16451. @publisher_db       sysname,
  16452. @publication        sysname,
  16453. @publication_type   int,
  16454. @subscriber         sysname,
  16455. @subscriber_db      sysname,
  16456. @article            sysname,
  16457. @destination_object sysname,
  16458. @source_object      sysname,
  16459. @alert_error_text   ntext
  16460. )
  16461. AS
  16462.     SET NOCOUNT ON
  16463.  
  16464.     INSERT INTO msdb.dbo.sysreplicationalerts (status, agent_type , agent_id, error_id, alert_error_code, time, publisher,
  16465.                                 publisher_db, publication, publication_type, subscriber, subscriber_db,
  16466.                                 article, destination_object, source_object, alert_error_text)
  16467.                 VALUES (0, @agent_type, @agent_id, @error_id, @alert_error_code, getdate(), @publisher, 
  16468.                         @publisher_db, @publication, @publication_type, @subscriber, @subscriber_db, 
  16469.                         @article, @destination_object, @source_object, @alert_error_text)
  16470.     
  16471.     IF @@ERROR <> 0
  16472.     BEGIN
  16473.        RETURN (1)
  16474.     END
  16475.  
  16476.     return (0)
  16477. GO   
  16478.  
  16479.  
  16480. raiserror(15339,-1,-1,'sp_MSget_repl_error')
  16481. GO
  16482.  
  16483. create procedure sp_MSget_repl_error (
  16484. @id int
  16485. )
  16486. as
  16487.     set nocount on
  16488.     select  source_type_id, source_name, error_code, error_text, 
  16489.             convert(nvarchar(12), time, 112) + 
  16490.             substring(convert(nvarchar(24), time, 121), 11, 13),
  16491.             error_type_id, 
  16492.             'has_xact_seqno' = case when xact_seqno is null or xact_seqno = 0x0
  16493.                 then convert(bit, 0) else convert(bit, 1) end,
  16494.             xact_seqno, command_id
  16495.         from MSrepl_errors
  16496.         where
  16497.             id = @id and
  16498.             -- rows with error_type_id are placeholders
  16499.             error_type_id IS NOT NULL
  16500.         order by time ASC
  16501. GO
  16502.  
  16503.  
  16504. raiserror(15339,-1,-1,'sp_MSdist_activate_auto_sub')
  16505. go
  16506. CREATE PROCEDURE sp_MSdist_activate_auto_sub
  16507. @publisher_id int,
  16508. @publisher_db sysname,
  16509. @article_id int
  16510.  
  16511. as
  16512.     
  16513.   declare @automatic tinyint
  16514.   declare @active tinyint
  16515.   declare @subscribed tinyint
  16516.  
  16517.    set nocount on
  16518.  
  16519.     select @automatic = 1
  16520.  
  16521.     select @subscribed = 1
  16522.     select @active = 2
  16523.  
  16524.     begin transaction MSdist_activate_auto_sub
  16525.  
  16526.        update MSsubscriptions set status = @active,
  16527.             subscription_time = getdate()
  16528.            where
  16529.               publisher_id = @publisher_id and
  16530.               publisher_db = @publisher_db and
  16531.               article_id = @article_id and
  16532.               sync_type = @automatic and
  16533.               status in( @subscribed )
  16534.  
  16535.        if @@ERROR <> 0
  16536.           begin
  16537.           if @@trancount > 0
  16538.             rollback transaction MSdist_activate_auto_sub
  16539.           return (1)
  16540.           end
  16541.  
  16542.    commit transaction
  16543.  
  16544. GO
  16545.  
  16546. raiserror(15339,-1,-1,'sp_MSlock_auto_sub')
  16547. go
  16548. CREATE PROCEDURE sp_MSlock_auto_sub
  16549. @publisher_id int,
  16550. @publisher_db sysname,
  16551. @publication sysname,
  16552. @reset bit = 0  /* @reset = 1 is used for Scheduled Snapshot publications by snapshot */
  16553.  
  16554. as
  16555.     
  16556.   /* This sp only work for 7.0 publisher since it use the publication name */  
  16557.    set nocount on
  16558.  
  16559.     DECLARE @virtual smallint     /* const: virtual subscriber id */
  16560.     DECLARE @virtual_anonymous smallint /* const: virtual anonymous subscriber id */
  16561.     DECLARE @subscribed tinyint
  16562.     DECLARE @automatic tinyint
  16563.     DECLARE @publication_id int
  16564.     DECLARE @counter int
  16565.     DECLARE @independent_agent bit
  16566.     DECLARE @active tinyint
  16567.  
  16568.     SELECT @virtual = -1
  16569.     SELECT @virtual_anonymous = -2
  16570.     SELECT @subscribed = 1
  16571.     SELECT @active = 2
  16572.     SELECT @automatic = 1
  16573.  
  16574.     select @publication_id = publication_id , @independent_agent = independent_agent
  16575.         from MSpublications 
  16576.         where 
  16577.         publisher_id = @publisher_id and
  16578.         publisher_db = @publisher_db and
  16579.         publication = @publication 
  16580.  
  16581.  
  16582.     /* 
  16583.     ** Set exclusive lock on the rows that will be updated to prevent deadlock 
  16584.     **      in snapshot agent.
  16585.     ** Note: using UPDATE lock may cause deadlock with sp_MSget_repl_commands as following
  16586.     ** 1. The distribution agent gets shared lock on MSsubscriptions.
  16587.     ** 2. The snapshot agent gets update lock on MSsubscriptions.
  16588.     ** 3. The snapshot agent gets exclusive lock on MSrepl_commands (inserting into the table)
  16589.     ** 4. The distribution agent waits to get shared lock on MSrepl_commands
  16590.     ** 5. The snapshot agent waits to convert update lock to exclusive lock on MSrepl_subscriptions (updating the table).
  16591.     */
  16592.     --SELECT @counter = COUNT(*) FROM MSsubscriptions (ROWLOCK UPDLOCK)
  16593.     -- 1. Avoid defered updates: Don't update fields in the clusted index
  16594.     -- 2. Avoid updating fields in the where clause 
  16595.     UPDATE MSsubscriptions SET update_mode = update_mode 
  16596.       WHERE 
  16597.          publisher_id = @publisher_id and
  16598.          publisher_db = @publisher_db and
  16599.          publication_id = @publication_id and 
  16600.          /* virtual subscriptions are automatic sync type */
  16601.          sync_type = @automatic and 
  16602.          (status = @subscribed or 
  16603.          subscriber_id = @virtual or
  16604.          subscriber_id = @virtual_anonymous or
  16605.          @reset = 1) 
  16606. GO
  16607.  
  16608. raiserror(15339,-1,-1,'sp_MSget_new_xact_seqno')
  16609. go
  16610. CREATE PROCEDURE sp_MSget_new_xact_seqno
  16611. @publisher_id int,
  16612. @publisher_db sysname,
  16613. @len    tinyint
  16614.  
  16615. AS
  16616.    declare @new_xact_seqno varbinary(16)
  16617.    declare @old_xact_seqno varbinary(16)
  16618.    declare @tag int
  16619.    declare @datalen tinyint
  16620.    declare @publisher_database_id int
  16621.  
  16622.    set nocount on 
  16623.    select @old_xact_seqno = NULL
  16624.  
  16625.     -- Get publisher database id.
  16626.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  16627.         publisher_db = @publisher_db
  16628.  
  16629.    set rowcount 1
  16630.    select @old_xact_seqno = rt.xact_seqno
  16631.       from
  16632.       -- Prevent inserts
  16633.       MSrepl_transactions rt (HOLDLOCK PAGLOCK UPDLOCK)
  16634.       where 
  16635.          rt.publisher_database_id = @publisher_database_id 
  16636.          order by xact_seqno desc
  16637.    set rowcount 0
  16638.  
  16639.    
  16640.    if @old_xact_seqno IS NULL
  16641.    begin
  16642.         /* if nothing got selected, lock the entire table 
  16643.         ** Don't return meta data !!
  16644.         */
  16645.        select @old_xact_seqno = rt.xact_seqno
  16646.           from
  16647.           MSrepl_transactions rt (HOLDLOCK TABLOCKX)
  16648.           where 0 = 1
  16649.  
  16650.         select @old_xact_seqno = subscription_seqno from MSsubscriptions 
  16651.         where
  16652.             publisher_database_id = @publisher_database_id and
  16653.             subscription_seqno = (select MAX(subscription_seqno) from MSsubscriptions rs2
  16654.             where
  16655.                 rs2.publisher_database_id = @publisher_database_id)
  16656.    end
  16657.  
  16658.     select @datalen = datalength(@old_xact_seqno) 
  16659.     /* Plus one to the tag */
  16660.     if @datalen = @len
  16661.     begin
  16662.         select @tag = convert( int, convert( binary(4), substring( convert( nvarchar, @old_xact_seqno ), @datalen/2 - 2 + 1,2 ) ) )
  16663.         
  16664.         if @tag = 0xffffffff
  16665.         begin
  16666.             raiserror(21018, 16, -1)
  16667.             return(1)
  16668.         end
  16669.         /* avoid arithmatic overflow */
  16670.         if @tag = 0x7fffffff
  16671.             select @tag = 0x80000000
  16672.         else 
  16673.             select @tag = @tag + 1
  16674.  
  16675.         select @new_xact_seqno = 
  16676.         convert( varbinary, substring( convert(nvarchar, @old_xact_seqno), 1, @datalen/2-2)) +
  16677.         convert( VARBINARY(4), @tag )
  16678.  
  16679.     end
  16680.     /* Add a tag */
  16681.     else
  16682.     begin
  16683.         if @datalen + 4 <> @len
  16684.         begin
  16685.             -- We are in trouble if we reach here.
  16686.             return(1)
  16687.         end
  16688.         select @tag = 1
  16689.         select @new_xact_seqno = 
  16690.             @old_xact_seqno + CONVERT(VARBINARY(4), @tag) 
  16691.     end
  16692.  
  16693.    select @new_xact_seqno
  16694. GO
  16695.  
  16696.  
  16697.  
  16698. raiserror(15339,-1,-1,'sp_MSchange_publication')
  16699. go
  16700.  CREATE PROCEDURE sp_MSchange_publication (
  16701.      @publisher sysname,
  16702.      @publisher_db sysname,
  16703.      @publication sysname,
  16704.      @property sysname,
  16705.      @value nvarchar(255)
  16706.      )
  16707. as
  16708. BEGIN
  16709.     set nocount on
  16710.     
  16711.      declare @publisher_id smallint
  16712.              ,@publication_type int
  16713.              ,@retcode int
  16714.              ,@max_distretention int
  16715.              ,@retention_value int
  16716.              ,@cmd    nvarchar(255)
  16717.              ,@cmd2   nvarchar(255)
  16718.              ,@cmd3   nvarchar(255)
  16719.  
  16720.     -- Check if publisher is a defined as a distribution publisher in the current database
  16721.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  16722.     if @retcode <> 0
  16723.     begin
  16724.         return(1)
  16725.     end
  16726.  
  16727.     /* Charater properties  */
  16728.  
  16729.     begin tran
  16730.  
  16731.     IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) ='description'
  16732.     BEGIN
  16733.         UPDATE MSpublications SET description = @value
  16734.             WHERE   publisher_id = @publisher_id AND
  16735.                     publisher_db = @publisher_db AND
  16736.                     publication = @publication
  16737.         IF @@ERROR <> 0 
  16738.             goto UNDO
  16739.     END
  16740.     ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) IN ('snapshot_agent')
  16741.     BEGIN
  16742.         -- local job name is internal and should not be changed
  16743.         if exists (select * from MSsnapshot_agents where
  16744.             publisher_id = @publisher_id and
  16745.             publication = @publication and
  16746.             publisher_db = @publisher_db and
  16747.             local_job = 1)
  16748.         begin
  16749.             raiserror(21030, 16, -1)
  16750.             goto UNDO
  16751.         end
  16752.  
  16753.         -- Drop and recreate
  16754.         exec @retcode = dbo.sp_MSdrop_snapshot_agent
  16755.             @publisher = @publisher,
  16756.             @publisher_db = @publisher_db,
  16757.             @publication = @publication
  16758.  
  16759.         IF @@ERROR <> 0 or @retcode <> 0
  16760.             goto UNDO
  16761.  
  16762.         exec @retcode = dbo.sp_MSadd_snapshot_agent
  16763.             @name = @value,
  16764.             @publisher = @publisher,
  16765.             @publisher_db = @publisher_db,
  16766.             @publication = @publication,
  16767.             @local_job = 0
  16768.  
  16769.         IF @@ERROR <> 0 or @retcode <> 0
  16770.             goto UNDO
  16771.     END
  16772.     ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) IN ('logreader_agent')
  16773.     BEGIN
  16774.         -- local job name is internal and should not be changed
  16775.         if exists (select * from MSlogreader_agents where
  16776.             publisher_id = @publisher_id and
  16777.             publication = @publication and
  16778.             publisher_db = @publisher_db and
  16779.             local_job = 1)
  16780.         begin
  16781.             raiserror(21030, 16, -1)
  16782.             goto UNDO
  16783.         end
  16784.  
  16785.         -- Drop and recreate
  16786.         exec @retcode = dbo.sp_MSdrop_logreader_agent
  16787.             @publisher = @publisher,
  16788.             @publisher_db = @publisher_db,
  16789.             @publication = @publication
  16790.  
  16791.         IF @@ERROR <> 0 or @retcode <> 0
  16792.             goto UNDO
  16793.  
  16794.         exec @retcode = dbo.sp_MSadd_logreader_agent
  16795.             @name = @value,
  16796.             @publisher = @publisher,
  16797.             @publisher_db = @publisher_db,
  16798.             @publication = @publication,
  16799.             @local_job = 0
  16800.  
  16801.         IF @@ERROR <> 0 or @retcode <> 0
  16802.             goto UNDO
  16803.     END
  16804.     ELSE if LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) IN ('retention')
  16805.     BEGIN
  16806.         select @retention_value = convert(int, @value)
  16807.         select @publication_type = publication_type
  16808.             from MSpublications
  16809.             WHERE   publisher_id = @publisher_id AND
  16810.                     publisher_db = @publisher_db AND
  16811.                     publication = @publication
  16812.         UPDATE MSpublications set retention=@retention_value 
  16813.         WHERE   publisher_id = @publisher_id AND
  16814.                     publisher_db = @publisher_db AND
  16815.                     publication = @publication
  16816.         if @@ERROR<>0
  16817.                 goto UNDO
  16818.     END
  16819.      ELSE if LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = ('queue_type')
  16820.      BEGIN
  16821.          --
  16822.          -- If we have come here, it is for MSMQ queue type.
  16823.          -- Distributor needs to support MSMQ 2.0 - Just check that
  16824.          --
  16825.          if (convert(int, @value) = 1)
  16826.          begin
  16827.              --
  16828.              -- Now we use xp_MSver to detect NT OS version
  16829.              -- MSMQ subscription only allowed for platforms that support MSMQ 2.0
  16830.              -- version 5.0.2195 or higher
  16831.              --
  16832.              create table #tosversion ( propid int, propname sysname collate database_default, value int, charvalue nvarchar(255) collate database_default)
  16833.              insert into #tosversion (propid, propname, value, charvalue)
  16834.                  exec master.dbo.xp_msver N'WindowsVersion'
  16835.  
  16836.              declare @vervalue int
  16837.                  ,@lobyte tinyint
  16838.                  ,@hibyte tinyint
  16839.                  ,@loword smallint
  16840.                  ,@hiword smallint
  16841.  
  16842.              --
  16843.              -- low order byte of low order word = OSmajor, high order byte of low order word = OSminor
  16844.              -- high order word = OSbuild
  16845.              --
  16846.              select @vervalue = value from #tosversion where propname = N'WindowsVersion'
  16847.              select @loword = (@vervalue & 0xffff)
  16848.                      ,@hiword = (@vervalue / 0x10000) & 0xffff
  16849.              select @lobyte = @loword & 0xff
  16850.                      ,@hibyte = (@loword / 100) & 0xff
  16851.              drop table #tosversion
  16852.  
  16853.              --
  16854.              -- check for OS major version
  16855.              --
  16856.              if (@lobyte < 5)
  16857.              begin
  16858.                  raiserror(21334, 16, 6, '2.0')
  16859.                  goto UNDO
  16860.              end
  16861.  
  16862.              --
  16863.              -- check for OS build version
  16864.              --
  16865.              if (@lobyte = 5 and @hiword < 2195)
  16866.              begin
  16867.                  raiserror(21334, 16, 7, '2.0')
  16868.                  goto UNDO
  16869.              end
  16870.          end
  16871.      END
  16872.     ELSE
  16873.     BEGIN
  16874.         SELECT @cmd = ''
  16875.         SELECT @cmd = @cmd + 'UPDATE MSpublications '
  16876.         SELECT @cmd = @cmd + '   SET ' + LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) + ' = '
  16877.         /* @value can be 255 nchars, so don't append it */
  16878.         SELECT @cmd2 = ' WHERE publisher_id = ' + STR(@publisher_id)
  16879.         SELECT @cmd2 =  @cmd2 + ' AND publisher_db = ' + quotename(@publisher_db,'''')
  16880.         SELECT @cmd2 =  @cmd2 + ' AND publication = '  + quotename(@publication, '''')
  16881.         EXECUTE (@cmd + @value + @cmd2)
  16882.         IF @@ERROR <> 0 
  16883.             goto UNDO
  16884.     END
  16885.  
  16886.     COMMIT TRAN
  16887.  
  16888.     RETURN(0)
  16889.  
  16890. UNDO:
  16891.     IF @@TRANCOUNT = 1
  16892.         ROLLBACK TRAN
  16893.     ELSE
  16894.         COMMIT TRAN   
  16895.     RETURN (1)
  16896. END
  16897. go
  16898.  
  16899.  
  16900. raiserror(15339,-1,-1,'sp_MSadd_article')
  16901. go
  16902. CREATE PROCEDURE sp_MSadd_article
  16903. @publisher sysname,
  16904. @publisher_db sysname,
  16905. @publication sysname,
  16906. @article sysname,
  16907. @article_id int = NULL,
  16908. @destination_object sysname = NULL,
  16909. @source_object sysname = NULL,
  16910. @description nvarchar(255) = NULL,
  16911. @source_owner   sysname = NULL
  16912. as
  16913.  
  16914.     set nocount on
  16915.  
  16916.     declare @publisher_id smallint
  16917.     declare @publication_id int
  16918.     declare @retcode int
  16919.     declare @thirdparty_flag bit
  16920.     declare @immediate_sync bit
  16921.     declare @allow_anonymous bit
  16922.     declare @subscription_seqno binary(16)
  16923.     declare @subscribed tinyint
  16924.     declare @active tinyint
  16925.  
  16926.     select @subscribed = 1  
  16927.     select @active = 2
  16928.         
  16929.     -- Check if publisher is a defined as a distribution publisher in the current database
  16930.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  16931.     if @retcode <> 0
  16932.     begin
  16933.         return(1)
  16934.     end
  16935.  
  16936.     -- Get publication id
  16937.     select @publication_id = publication_id,  
  16938.         @thirdparty_flag = thirdparty_flag,
  16939.         @immediate_sync = immediate_sync, @allow_anonymous = allow_anonymous 
  16940.         from MSpublications where
  16941.         publisher_id = @publisher_id and 
  16942.         publisher_db = @publisher_db and
  16943.         publication = @publication
  16944.     if @publication_id is NULL
  16945.     begin
  16946.         raiserror (20026, 11, -1, @publication)
  16947.         return (1)
  16948.     end
  16949.  
  16950.     -- Make sure article does not already exist
  16951.     if exists (select * from MSarticles where publication_id = @publication_id and
  16952.         publisher_id = @publisher_id and publisher_db = @publisher_db and article = @article)
  16953.     begin
  16954.         if @thirdparty_flag = 1
  16955.         begin
  16956.             raiserror (14030, 16, -1, @article, @publication)
  16957.             return (1)
  16958.         end
  16959.         else
  16960.         begin
  16961.             exec @retcode = dbo.sp_MSdrop_article
  16962.                 @publisher = @publisher,
  16963.                 @publisher_db = @publisher_db,
  16964.                 @publication = @publication,
  16965.                 @article = @article
  16966.             if @retcode <> 0 or @@error <> 0
  16967.             begin
  16968.                 return (1)
  16969.             end
  16970.         end
  16971.     end
  16972.  
  16973.     -- If it is a third party publication - check if a subscription exists
  16974.     -- for the publication already. If it does then we cannot add any
  16975.     -- articles - the existing subscriptions will have to dropped first and then
  16976.     -- resubscribed
  16977.     -- excluding virtual subscriptions.
  16978.     if (@thirdparty_flag = 1)
  16979.     begin
  16980.         if exists (select * from MSsubscriptions where 
  16981.                 publisher_id = @publisher_id and 
  16982.                 publisher_db = @publisher_db and 
  16983.                 publication_id = @publication_id and
  16984.                 subscriber_id >= 0)
  16985.         begin
  16986.             raiserror(21131, 16, -1, @publication)
  16987.             return (1)
  16988.         end
  16989.     end
  16990.  
  16991.     begin tran
  16992.     save tran MSadd_article
  16993.  
  16994.     -- Generate new article id when one is not provided by a 
  16995.     -- third party publisher or merge publication
  16996.     if @article_id is NULL
  16997.     begin
  16998.         if (@thirdparty_flag = 1)
  16999.         begin
  17000.             -- Generate unique id per publisher
  17001.             select @article_id = max(article_id) + 1 from MSarticles where 
  17002.                 publisher_id = @publisher_id
  17003.         end
  17004.         else
  17005.         begin
  17006.             -- 6.5 behavior : retain for compatibility
  17007.             -- NOTE: article_id is incremented per publisher/publisher_db/publication
  17008.             select @article_id = max(article_id) + 1 from MSarticles where 
  17009.                 publisher_id = @publisher_id and
  17010.                 publisher_db = @publisher_db and
  17011.                 publication_id = @publication_id
  17012.         end
  17013.  
  17014.         if @article_id is null
  17015.             select @article_id = 1
  17016.     end
  17017.     else
  17018.     begin
  17019.         --
  17020.         -- for third party publisher - validate the article id
  17021.         --
  17022.         if (@thirdparty_flag = 1)
  17023.         begin
  17024.             if exists (select * from MSarticles where
  17025.                     article_id = @article_id and
  17026.                     publisher_id = @publisher_id and
  17027.                     publisher_db = @publisher_db and
  17028.                     publication_id = @publication_id)
  17029.             begin
  17030.                 if @@trancount > 0
  17031.                 begin
  17032.                     rollback tran MSadd_article
  17033.                     commit tran
  17034.                 end
  17035.                 raiserror (14155, 16, 2)
  17036.                 return (1)
  17037.             end
  17038.         end
  17039.     end
  17040.  
  17041.     insert into MSarticles values (@publisher_id, @publisher_db, @publication_id,
  17042.         @article, @article_id, @destination_object, @source_owner, @source_object, @description)
  17043.     if @@error <> 0
  17044.     begin
  17045.         if @@trancount > 0
  17046.         begin
  17047.             rollback tran MSadd_article
  17048.             commit tran
  17049.         end
  17050.         return (1)
  17051.     end
  17052.  
  17053.     -- For third party publications create immediate sync and anonymous virtual subscription
  17054.     -- with 'subscribed' status and then change anonymous virtual to 'active' status
  17055.     -- SQL Server publications will do this via RPC calls to sp_MSadd_subscription
  17056.     if @thirdparty_flag = 1 
  17057.     begin
  17058.         select @subscription_seqno = 0x00  
  17059.         if @immediate_sync = 1
  17060.         begin
  17061.             -- @status passed to sp_MSadd_subscription should always be @subscribed.
  17062.             exec @retcode = dbo.sp_MSadd_subscription
  17063.                 @publisher = @publisher,
  17064.                 @publisher_db = @publisher_db,
  17065.                 @publication = @publication,
  17066.                 @article_id = @article_id,
  17067.                 @subscriber = NULL,                 -- virtual subscription
  17068.                 @status = @subscribed,              
  17069.                 @subscription_seqno = @subscription_seqno,
  17070.                 @sync_type = 1  -- virtual subscriptions are automatic sync type 
  17071.             if @retcode <> 0 or @@error <> 0
  17072.             begin
  17073.                 if @@trancount > 0
  17074.                 begin
  17075.                     rollback tran MSadd_article
  17076.                     commit tran
  17077.                 end
  17078.                 return (1)
  17079.             end
  17080.             -- For SQL publications, we have logic to immediately active the 
  17081.             -- virtual anonymous subscription to no_sync subscriptions. However, this
  17082.             -- feature is not exposed (You need to pass undocumented command line arg 
  17083.             -- '-NoInitialSync' to the distribution agent for the anonymous subscription).
  17084.             -- Do the same for 3rd party publications
  17085.  
  17086.             if @allow_anonymous = 1
  17087.             begin
  17088. /*
  17089. @publisher sysname,
  17090. @publisher_db sysname,
  17091. @subscriber sysname,
  17092. @article_id int,
  17093. @status int,
  17094. @subscription_seqno varbinary(16),
  17095. --post 6x
  17096. @destination_db sysname = '%'
  17097. */
  17098.                 exec @retcode = dbo.sp_MSupdate_subscription
  17099.                     @publisher = @publisher,
  17100.                     @publisher_db = @publisher_db,
  17101.                     @subscriber = NULL,                 -- virtual subscription
  17102.                     @article_id = @article_id,
  17103.                     @status = @active,              
  17104.                     @subscription_seqno = @subscription_seqno,
  17105.                     @destination_db = '%' -- For virtual sub, @destination_db is not used. Can pass in anything
  17106.                 if @retcode <> 0 or @@error <> 0
  17107.                 begin
  17108.                     if @@trancount > 0
  17109.                     begin
  17110.                         rollback tran MSadd_article
  17111.                         commit tran
  17112.                     end
  17113.                     return (1)
  17114.                 end
  17115.             end
  17116.         end
  17117.     end
  17118.  
  17119.     commit tran
  17120. go
  17121.  
  17122. raiserror(15339,-1,-1,'sp_MSchange_article')
  17123. go
  17124. CREATE PROCEDURE sp_MSchange_article
  17125. @publisher sysname,
  17126. @publisher_db sysname,
  17127. @publication sysname,
  17128. @article sysname,
  17129. @article_id int,
  17130. @property nvarchar(20) = NULL,
  17131. @value nvarchar(255) = NULL
  17132. AS
  17133.     DECLARE @retcode int
  17134.     DECLARE @publisher_id smallint
  17135.     DECLARE @publication_id int
  17136.     declare @tablename sysname
  17137.  
  17138.     -- Get publisher id
  17139.  
  17140.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  17141.     if @retcode <> 0
  17142.     begin
  17143.         return(1)
  17144.     end
  17145.  
  17146.     -- lower case property
  17147.     select @property = lower (@property)
  17148.     
  17149.     -- Get publication id
  17150.  
  17151.     select @publication_id = publication_id
  17152.         from MSpublications where
  17153.         publisher_id = @publisher_id and 
  17154.         publisher_db = @publisher_db and
  17155.         publication = @publication
  17156.     if @publication_id is NULL
  17157.     begin
  17158.         raiserror (20026, 11, -1, @publication)
  17159.         return (1)
  17160.     end
  17161.  
  17162.     if @property = N'description'     
  17163.     begin
  17164.         update MSarticles set description = @value
  17165.         where publisher_id = @publisher_id
  17166.         and publisher_db = @publisher_db
  17167.         and publication_id = @publication_id
  17168.         and article = @article
  17169.         and article_id = @article_id
  17170.         if @@error <> 0
  17171.         begin
  17172.             return 1
  17173.         end
  17174.     end
  17175.     else if @property in( N'dest_table', N'dest_object' )
  17176.     begin
  17177.         update MSarticles set destination_object = @value
  17178.         where publisher_id = @publisher_id
  17179.         and publisher_db = @publisher_db
  17180.         and publication_id = @publication_id
  17181.         and article = @article
  17182.         and article_id = @article_id
  17183.         if @@error <> 0
  17184.         begin
  17185.             return 1
  17186.         end
  17187.     end
  17188.     else if @property = 'identity_range'
  17189.     begin
  17190.         declare @range bigint
  17191.         select @range = convert(bigint, @value)
  17192.         select @tablename = source_object from MSarticles 
  17193.             where publisher_id = @publisher_id
  17194.             and publisher_db = @publisher_db
  17195.             and publication_id = @publication_id
  17196.             and article = @article
  17197.             and article_id = @article_id
  17198.  
  17199.         update MSrepl_identity_range set range = @range where
  17200.             publisher = @publisher and
  17201.             publisher_db = @publisher_db and
  17202.             tablename = @tablename
  17203.         if @@error <> 0
  17204.         begin
  17205.             return 1
  17206.         end
  17207.     end
  17208.     else if @property = 'threshold'
  17209.     begin
  17210.         declare @threshold int
  17211.         select @threshold = convert(int, @value)
  17212.         select @tablename = source_object from MSarticles 
  17213.             where publisher_id = @publisher_id
  17214.             and publisher_db = @publisher_db
  17215.             and publication_id = @publication_id
  17216.             and article = @article
  17217.             and article_id = @article_id
  17218.  
  17219.         update MSrepl_identity_range set threshold = @threshold where
  17220.             publisher = @publisher and
  17221.             publisher_db = @publisher_db and
  17222.             tablename = @tablename
  17223.         if @@error <> 0
  17224.         begin
  17225.             return 1
  17226.         end
  17227.     end
  17228.     else
  17229.     begin
  17230.         return 1
  17231.     end
  17232. go
  17233.  
  17234.  
  17235. raiserror(15339,-1,-1,'sp_MShelp_publication')
  17236. go   
  17237. CREATE PROCEDURE sp_MShelp_publication (
  17238. @publisher sysname,
  17239. @publisher_db sysname = '%',
  17240. @publication sysname = '%')
  17241. as
  17242. BEGIN
  17243.     set nocount on
  17244.     declare    @queued_agent sysname
  17245.  
  17246.     if @publisher_db != '%' and @publication != '%' and not exists (select * from MSpublications where
  17247.         publisher_id = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)) and
  17248.         ((@publisher_db = N'%') or (publisher_db = @publisher_db)) and
  17249.         publication like @publication)
  17250.     begin
  17251.         raiserror(20026, 16, -1, @publication)
  17252.         return(1)
  17253.     end
  17254.  
  17255.     select @queued_agent = name from MSqreader_agents 
  17256.     select p.publisher_db, p.publication, p.publication_id, p.publication_type, 
  17257.         --thirdparty_flag, 
  17258.         independent_agent,
  17259.         immediate_sync, allow_push, allow_pull, allow_anonymous, 'snapshot_agent' = s.name,
  17260.         'logreader_agent' = l.name, p.description, vendor_name 
  17261.         -- queue reader agent only if we have valid queued subscription
  17262.         ,'queuereader agent' = case 
  17263.             when (exists (select * from MSsubscriptions sub where sub.publisher_id = p.publisher_id and
  17264.                         sub.publisher_db = p.publisher_db and sub.publication_id = p.publication_id and
  17265.                         (sub.update_mode in (2,3,4,5)))) 
  17266.             then @queued_agent else NULL end
  17267.         ,'thirdparty_options' = thirdparty_options
  17268.         ,'snapshot_jobid' = j.job_id
  17269.         from MSpublications p  
  17270.         LEFT OUTER JOIN MSsnapshot_agents s
  17271.         ON
  17272.         s.publisher_id = p.publisher_id and
  17273.         s.publisher_db = p.publisher_db and
  17274.         s.publication = p.publication
  17275.         LEFT OUTER JOIN MSlogreader_agents l
  17276.         ON
  17277.         (l.publisher_id = p.publisher_id and
  17278.         l.publisher_db = p.publisher_db and
  17279.         p.publication_type = 0 and              -- Only Transactional Publication has a  Log Reader
  17280.         (l.publication = p.publication OR
  17281.          thirdparty_flag = 0))
  17282.         LEFT OUTER JOIN msdb..sysjobs_view j
  17283.         ON
  17284.         s.job_id = j.job_id
  17285.       where 
  17286.         p.publisher_id = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)) and
  17287.         ((@publisher_db = N'%') or (p.publisher_db = @publisher_db)) and
  17288.         p.publication like @publication
  17289. END
  17290. go
  17291.  
  17292. raiserror(15339,-1,-1,'sp_MShelp_article')
  17293. go
  17294. CREATE PROCEDURE sp_MShelp_article 
  17295. @publisher sysname,
  17296. @publisher_db sysname,
  17297. @publication sysname,        
  17298. @article sysname = '%'
  17299. as
  17300.  
  17301.     set nocount on
  17302.  
  17303.     select article, article_id, source_object, description, source_owner from MSarticles a where 
  17304.         a.publisher_id = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)) and 
  17305.         a.publisher_db = @publisher_db and
  17306.         a.publication_id = (select publication_id from MSpublications where 
  17307.             publisher_id = a.publisher_id and
  17308.             publisher_db = a.publisher_db and
  17309.             publication = @publication) and
  17310.         a.article like @article
  17311. go
  17312.  
  17313. raiserror(15339,-1,-1,'sp_MShelp_subscription')
  17314. go
  17315. CREATE PROCEDURE sp_MShelp_subscription 
  17316. @publisher sysname,
  17317. @publisher_db sysname,
  17318. @publication sysname,        
  17319. @subscriber sysname = '%',              
  17320. @subscriber_db sysname = '%'
  17321. as
  17322. set nocount on
  17323.  
  17324.     select distinct ss.srvname + ':' + s.subscriber_db, ss.srvname, s.subscriber_db, s.subscription_type, 
  17325.         sync_type, status, agent.name, agent.job_id from 
  17326.         MSsubscriptions s, master..sysservers ss, MSdistribution_agents agent where 
  17327.         s.publisher_id = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)) and 
  17328.         s.publisher_db = @publisher_db and
  17329.         s.publication_id = (select publication_id from MSpublications where 
  17330.             publisher_id = s.publisher_id and
  17331.             publisher_db = s.publisher_db and
  17332.             publication = @publication) and
  17333.         ((@subscriber_db = N'%') or (s.subscriber_db = @subscriber_db)) and
  17334.         s.subscriber_id = ss.srvid and
  17335.         ((@subscriber = N'%') or (UPPER(ss.srvname) = UPPER(@subscriber))) and
  17336.         s.subscriber_id >= 0 and                    -- ignore virtual subscriptions
  17337.         s.agent_id = agent.id
  17338. go
  17339.  
  17340. raiserror(15339,-1,-1,'sp_MSadd_subscription_3rd')
  17341. go
  17342. CREATE PROCEDURE sp_MSadd_subscription_3rd
  17343. @publisher sysname,
  17344. @publisher_db sysname,
  17345. @publication sysname,
  17346. @subscriber sysname,       
  17347. @subscriber_db sysname = NULL,
  17348. @status tinyint,                    -- 0 = inactive, 1 = subscribed, 2 = active 
  17349. @subscription_type tinyint = 0,     -- 0 = push, 1 = pull, 2 = anonymous 
  17350. @sync_type tinyint = 2,             -- 0 = none  1 = automatic snaphot  2 = no intial snapshot
  17351.  
  17352. @frequency_type int = NULL,
  17353. @frequency_interval int = NULL,
  17354. @frequency_relative_interval int = NULL,
  17355. @frequency_recurrence_factor int = NULL,
  17356. @frequency_subday int = NULL,
  17357. @frequency_subday_interval int = NULL,
  17358. @active_start_time_of_day int = NULL,
  17359. @active_end_time_of_day int = NULL,
  17360. @active_start_date int = NULL,
  17361. @active_end_date int = NULL,
  17362.  
  17363. @distribution_jobid binary(8) = NULL OUTPUT
  17364.  
  17365. as
  17366.     set nocount on
  17367.  
  17368.     declare @retcode int
  17369.     declare @publication_id int
  17370.     declare @article_id int
  17371.     declare @virtual_id smallint
  17372.     declare @publisher_id smallint
  17373.     declare @immediate_sync bit
  17374.     declare @allow_push bit
  17375.     declare @allow_pull bit
  17376.     declare @allow_anonymous bit
  17377.     declare @subscription_seqno binary(16)
  17378.  
  17379.     select @virtual_id = -1
  17380.  
  17381.     -- Check if publisher is a defined as a distribution publisher in the current database
  17382.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  17383.     if @retcode <> 0
  17384.     begin
  17385.         return(1)
  17386.     end
  17387.  
  17388.     -- Get publication information
  17389.     select @publication_id = publication_id, @immediate_sync = immediate_sync,
  17390.         @allow_push = allow_push, @allow_pull = allow_pull, @allow_anonymous = allow_anonymous
  17391.         from MSpublications where
  17392.         publisher_id = @publisher_id and
  17393.         publisher_db = @publisher_db and
  17394.         publication = @publication
  17395.     if @publication_id is null
  17396.     begin
  17397.         raiserror(14016, 16, -1, @publication)
  17398.         return (1)
  17399.     end
  17400.  
  17401.     -- Check if publication supports subscription type
  17402.     if @subscription_type = 0 and @allow_push != 1
  17403.     begin
  17404.         raiserror(20034, 16, -1, @publication, 'push')
  17405.         return (1)
  17406.     end
  17407.     else if @subscription_type = 1 and @allow_pull != 1
  17408.     begin
  17409.         raiserror(20034, 16, -1, @publication, 'pull')
  17410.         return (1)
  17411.     end
  17412.     else if @subscription_type = 2 and @allow_anonymous != 1
  17413.     begin
  17414.         raiserror(20034, 16, -1, @publication, 'anonymous')
  17415.         return (1)
  17416.     end
  17417.  
  17418.     begin tran
  17419.     save tran MSadd_subscription_3rd
  17420.  
  17421.     -- Add a subscription for each article in the publication
  17422.     declare hCMSadd_subscription_3rd CURSOR LOCAL FAST_FORWARD FOR 
  17423.         select article_id from MSarticles a where
  17424.             a.publisher_id = @publisher_id and
  17425.             a.publisher_db = @publisher_db and
  17426.             a.publication_id = @publication_id
  17427.         for read only
  17428.  
  17429.     open hCMSadd_subscription_3rd
  17430.     fetch hCMSadd_subscription_3rd into @article_id
  17431.         
  17432.     while (@@fetch_status <> -1)
  17433.     begin
  17434.         if @immediate_sync = 1
  17435.             select @subscription_seqno = subscription_seqno from MSsubscriptions where
  17436.                 publisher_id = @publisher_id and
  17437.                 publisher_db = @publisher_db and
  17438.                 article_id = @article_id and
  17439.                 subscriber_id = @virtual_id 
  17440.         else
  17441.             select @subscription_seqno = 0x00 
  17442.  
  17443.         exec @retcode = dbo.sp_MSadd_subscription
  17444.             @publisher = @publisher,
  17445.             @publisher_db = @publisher_db,
  17446.             @publication = @publication,        -- Must provide this
  17447.             @article_id = @article_id,
  17448.             @subscriber = @subscriber,       
  17449.             @subscriber_db = @subscriber_db,
  17450.             @status = @status,
  17451.             @subscription_seqno = @subscription_seqno,
  17452.             @subscription_type = @subscription_type,
  17453.             @sync_type = @sync_type,
  17454.  
  17455.             @frequency_type = @frequency_type,
  17456.             @frequency_interval = @frequency_interval,
  17457.             @frequency_relative_interval = @frequency_relative_interval,
  17458.             @frequency_recurrence_factor = @frequency_recurrence_factor,
  17459.             @frequency_subday = @frequency_subday,
  17460.             @frequency_subday_interval = @frequency_subday_interval,
  17461.             @active_start_time_of_day = @active_start_time_of_day,
  17462.             @active_end_time_of_day = @active_end_time_of_day,
  17463.             @active_start_date = @active_start_date,
  17464.             @active_end_date = @active_end_date,
  17465.  
  17466.             @distribution_jobid = @distribution_jobid output
  17467.         if @retcode != 0 or @@error != 0
  17468.         begin
  17469.             close hCMSadd_subscription_3rd
  17470.             deallocate hCMSadd_subscription_3rd
  17471.             if @@trancount > 0
  17472.             begin
  17473.                 rollback tran MSadd_subscription_3rd
  17474.                 commit tran
  17475.             end
  17476.             return(1)
  17477.         end
  17478.  
  17479.         fetch hCMSadd_subscription_3rd into @article_id
  17480.     end
  17481.  
  17482.     close hCMSadd_subscription_3rd
  17483.     deallocate hCMSadd_subscription_3rd
  17484.  
  17485.     -- If article_id is null, there were no articles defined for the publication
  17486.     if @article_id is NULL
  17487.     begin
  17488.         raiserror(14009, 16, -1, @publication)
  17489.         if @@trancount > 0
  17490.         begin
  17491.             rollback tran MSadd_subscription_3rd
  17492.             commit tran
  17493.         end
  17494.         return (1)
  17495.     end
  17496.  
  17497.     commit tran
  17498.  
  17499. go
  17500.  
  17501. raiserror(15339,-1,-1,'sp_MSdrop_subscription_3rd')
  17502. go
  17503. CREATE PROCEDURE sp_MSdrop_subscription_3rd
  17504. @publisher sysname,
  17505. @publisher_db sysname,
  17506. @publication sysname,
  17507. @subscriber sysname,       
  17508. @subscriber_db sysname = NULL
  17509.  
  17510. as
  17511.     set nocount on
  17512.  
  17513.     declare @retcode int
  17514.     declare @article_id int
  17515.     declare @publisher_id smallint
  17516.     declare @publication_id int
  17517.  
  17518.     -- Check if publisher is a defined as a distribution publisher in the current database
  17519.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  17520.     if @retcode <> 0
  17521.     begin
  17522.         return(1)
  17523.     end
  17524.  
  17525.     -- Get publication information
  17526.     select @publication_id = publication_id from MSpublications where
  17527.         publisher_id = @publisher_id and
  17528.         publisher_db = @publisher_db and
  17529.         publication = @publication
  17530.     if @publication_id is null
  17531.     begin
  17532.         raiserror(14016, 16, -1, @publication)
  17533.         return (1)
  17534.     end
  17535.  
  17536.     begin tran
  17537.     save tran MSdrop_subscription_3rd
  17538.  
  17539.     -- Drop the subscription for each article in the publication
  17540.     if lower(@subscriber) = 'all' and lower(@subscriber_db) = 'all'
  17541.     begin
  17542.         declare hCMSdrop_subscription_3rd CURSOR LOCAL FAST_FORWARD FOR 
  17543.             select a.article_id, srv.srvname, sub.subscriber_db 
  17544.                 from MSarticles a, MSsubscriptions sub, master..sysservers srv where
  17545.                 a.publisher_id = @publisher_id and
  17546.                 a.publisher_db = @publisher_db and
  17547.                 a.publication_id = @publication_id and
  17548.                 sub.article_id = a.article_id and
  17549.                 sub.publisher_id = @publisher_id and
  17550.                 sub.publisher_db = @publisher_db and
  17551.                 sub.publication_id = @publication_id and
  17552.                 srv.srvid = sub.subscriber_id and
  17553.                 sub.subscriber_id >= 0
  17554.             union
  17555.             -- For virtual subscriptions
  17556.             select a.article_id, convert(sysname, null), convert(sysname, null)
  17557.                 from MSarticles a where
  17558.                 a.publisher_id = @publisher_id and
  17559.                 a.publisher_db = @publisher_db and
  17560.                 a.publication_id = @publication_id and
  17561.                 exists (select * from MSsubscriptions sub where
  17562.                     sub.article_id = a.article_id and
  17563.                     sub.publisher_id = @publisher_id and
  17564.                     sub.publisher_db = @publisher_db and
  17565.                     sub.publication_id = @publication_id and
  17566.                     sub.subscriber_id <0 )
  17567.             for read only
  17568.     end
  17569.     else
  17570.         declare hCMSdrop_subscription_3rd CURSOR LOCAL FAST_FORWARD FOR 
  17571.             select article_id, @subscriber, @subscriber_db from MSarticles a where
  17572.                 a.publisher_id = @publisher_id and
  17573.                 a.publisher_db = @publisher_db and
  17574.                 a.publication_id = @publication_id
  17575.             for read only
  17576.  
  17577.     open hCMSdrop_subscription_3rd
  17578.     fetch hCMSdrop_subscription_3rd into @article_id, @subscriber, @subscriber_db
  17579.         
  17580.     while (@@fetch_status <> -1)
  17581.     begin
  17582.         exec @retcode = dbo.sp_MSdrop_subscription
  17583.             @publisher = @publisher,
  17584.             @publisher_db = @publisher_db,
  17585.             @publication = @publication,        -- Must provide this
  17586.             @article_id = @article_id,
  17587.             @subscriber = @subscriber,       
  17588.             @subscriber_db = @subscriber_db
  17589.         if @retcode != 0 or @@error != 0
  17590.         begin
  17591.             close hCMSdrop_subscription_3rd
  17592.             deallocate hCMSdrop_subscription_3rd
  17593.             if @@trancount > 0
  17594.             begin
  17595.                 rollback tran MSdrop_subscription_3rd
  17596.                 commit tran
  17597.             end
  17598.             return (1)
  17599.         end
  17600.  
  17601.        fetch hCMSdrop_subscription_3rd into @article_id, @subscriber, @subscriber_db
  17602.     end
  17603.  
  17604.     close hCMSdrop_subscription_3rd
  17605.     deallocate hCMSdrop_subscription_3rd
  17606.     commit tran
  17607. go
  17608.  
  17609. raiserror(15339,-1,-1,'sp_MSactivate_subscriptions')
  17610. go
  17611.  
  17612. CREATE PROCEDURE sp_MSactivate_subscriptions
  17613. @publisher_id int,
  17614. @publisher_db sysname,
  17615. @publication_id int, 
  17616. @xact_seqno varbinary(16),
  17617. @reset bit = 0      /* @reset = 1 is used for Scheduled Snapshot publications by snapshot */
  17618. AS
  17619.  
  17620.     declare @article_id int
  17621.     declare @retcode int
  17622.  
  17623.     declare hCseqno_3rd CURSOR LOCAL FAST_FORWARD FOR 
  17624.         select article_id from MSarticles a where
  17625.             a.publisher_id = @publisher_id and
  17626.             a.publisher_db = @publisher_db and
  17627.             a.publication_id = @publication_id
  17628.         for read only
  17629.  
  17630.     open hCseqno_3rd
  17631.     fetch hCseqno_3rd into @article_id
  17632.         
  17633.     while (@@fetch_status <> -1)
  17634.     begin
  17635.         select @article_id
  17636.         select @xact_seqno
  17637.         exec @retcode = dbo.sp_MSset_snapshot_xact_seqno
  17638.             @publisher_id = @publisher_id,
  17639.             @publisher_db = @publisher_db,
  17640.             @article_id = @article_id,
  17641.             @xact_seqno = @xact_seqno,
  17642.             @reset = @reset
  17643.         if @retcode != 0 or @@error != 0
  17644.         begin
  17645.             close hCseqno_3rd
  17646.             deallocate hCseqno_3rd
  17647.             return(1)
  17648.         end
  17649.  
  17650.         -- Activate the subscriptions
  17651.         exec @retcode = dbo.sp_MSdist_activate_auto_sub
  17652.             @publisher_id = @publisher_id,
  17653.             @publisher_db = @publisher_db,
  17654.             @article_id = @article_id
  17655.         if @retcode != 0 or @@error != 0
  17656.         begin
  17657.             close hCseqno_3rd
  17658.             deallocate hCseqno_3rd
  17659.             return(1)
  17660.         end
  17661.  
  17662.         fetch hCseqno_3rd into @article_id
  17663.     end
  17664.  
  17665.     close hCseqno_3rd
  17666.     deallocate hCseqno_3rd
  17667. GO
  17668. raiserror(15339,-1,-1,'sp_MSdrop_merge_subscription')
  17669. GO
  17670.  
  17671. CREATE PROCEDURE sp_MSdrop_merge_subscription
  17672. @publisher          sysname,
  17673. @publisher_db       sysname,
  17674. @publication        sysname,
  17675. @subscriber         sysname,
  17676. @subscriber_db      sysname,
  17677. @subscription_type  nvarchar(15) = 'push'           /* Subscription type - push, pull, both */ 
  17678.  
  17679. as
  17680.  
  17681.     set nocount on
  17682.  
  17683.     declare @publisher_id smallint
  17684.     declare @subscriber_id smallint
  17685.     declare @retcode int
  17686.     declare @publication_id int
  17687.     declare @job_id binary(16)
  17688.     declare @thirdparty_flag bit
  17689.     declare @id                 int
  17690.     declare @keep_for_last_run  bit
  17691.  
  17692.     -- Check if publisher is a defined as a distribution publisher in the current database
  17693.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  17694.     if @retcode <> 0
  17695.     begin
  17696.         return(1)
  17697.     end
  17698.  
  17699.     -- Check if subscriber exists
  17700.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber) 
  17701.     if @subscriber_id is NULL
  17702.     begin
  17703.         raiserror (20032, 16, -1, @subscriber, @publisher) 
  17704.         return (1)
  17705.     end
  17706.  
  17707.     -- Check if the publication exists
  17708.     select @publication_id = publication_id,
  17709.         @thirdparty_flag = thirdparty_flag
  17710.         from MSpublications where
  17711.         publisher_id = @publisher_id and
  17712.         publisher_db = @publisher_db and
  17713.         publication = @publication
  17714.     if @publication_id is NULL
  17715.     begin
  17716.         raiserror (20026, 16, -1, @publication) 
  17717.        return (1)
  17718.     end
  17719.  
  17720.     -- Check that subscription exists
  17721.     if not exists (select * from MSmerge_subscriptions where 
  17722.         publisher_id = @publisher_id and 
  17723.         publisher_db = @publisher_db and 
  17724.         publication_id = @publication_id and
  17725.         subscriber_id = @subscriber_id and
  17726.         subscriber_db = @subscriber_db)
  17727.     begin
  17728.         if @thirdparty_flag = 1
  17729.         begin
  17730.             --UNDONE : Add this back again when we add pull subscriptions metedata at the distributor
  17731.             --raiserror (14050, 10, -1)
  17732.             return(1)
  17733.         end
  17734.         else
  17735.             return (0)
  17736.     end
  17737.  
  17738.     begin tran
  17739.     save transaction MSdrop_merge_subscription
  17740.  
  17741.     -- Delete the subscription 
  17742.     -- For anonymous type, delete virtual anonymous subscription also
  17743.     -- if deleting the  virtual subscription 
  17744.     -- (since there can be only one subscriber_id per article, subscriber_db doesn't matter)
  17745.     delete from MSmerge_subscriptions where
  17746.         publisher_id = @publisher_id and
  17747.         publisher_db = @publisher_db and
  17748.         publication_id = @publication_id and
  17749.         subscriber_id = @subscriber_id and
  17750.         subscriber_db = @subscriber_db
  17751.     if @@error <> 0
  17752.     begin
  17753.         goto FAILURE
  17754.     end
  17755.  
  17756.     /*
  17757.     ** Get agentid to check history record
  17758.     */
  17759.     select @id=id from MSmerge_agents where 
  17760.         publisher_id = @publisher_id and
  17761.         publisher_db = @publisher_db and
  17762.         publication = @publication and
  17763.         subscriber_id = @subscriber_id and
  17764.         subscriber_db = @subscriber_db
  17765.  
  17766.     /*
  17767.     ** If the subscription has not yet been synced, there is no need for subscriber side cleanup 
  17768.     ** therefore no need for the last agent run.
  17769.     */
  17770.     if exists (select * from MSmerge_history where agent_id = @id) and @subscription_type='push'
  17771.         select @keep_for_last_run = 0 -- cleanup code is not activated.
  17772.     else 
  17773.         select @keep_for_last_run = 0
  17774.     
  17775.     /*
  17776.     ** Delete Merge agent and meta data, if it exists
  17777.     */
  17778.     EXECUTE @retcode = dbo.sp_MSdrop_merge_agent 
  17779.         @publisher = @publisher,
  17780.         @publisher_db = @publisher_db,
  17781.         @publication = @publication,
  17782.         @subscriber = @subscriber,
  17783.         @subscriber_db = @subscriber_db,
  17784.         @keep_for_last_run = @keep_for_last_run
  17785.     if @@error <> 0 or @retcode <> 0
  17786.     begin
  17787.         goto FAILURE
  17788.     end
  17789.  
  17790.     commit transaction
  17791.     return 0
  17792. FAILURE:
  17793.     if @@trancount > 0
  17794.     begin   
  17795.         ROLLBACK TRANSACTION MSdrop_merge_subscription
  17796.         COMMIT TRANSACTION
  17797.     end
  17798.     return 1
  17799.         
  17800. GO
  17801.  
  17802. raiserror(15339,-1,-1,'sp_MSadd_merge_subscription')
  17803. GO
  17804. CREATE PROCEDURE sp_MSadd_merge_subscription
  17805. @publisher sysname,
  17806. @publisher_db sysname,
  17807. @publication sysname,
  17808. @subscriber sysname,       
  17809. @subscriber_db sysname,
  17810. @subscription_type tinyint = 0,     -- 0 = push, 1 = pull
  17811. @sync_type tinyint = 1,             -- 0 = none  1 = automatic snaphot  2 = no intial snapshot
  17812. @status tinyint = 1,                -- 0 = inactive, 1 = subscribed, 2 = active 
  17813. @frequency_type int = NULL,
  17814. @frequency_interval int = NULL,
  17815. @frequency_relative_interval int = NULL,
  17816. @frequency_recurrence_factor int = NULL,
  17817. @frequency_subday int = NULL,
  17818. @frequency_subday_interval int = NULL,
  17819. @active_start_time_of_day int = NULL,
  17820. @active_end_time_of_day int = NULL,
  17821. @active_start_date int = NULL,
  17822. @active_end_date int = NULL,
  17823. @optional_command_line nvarchar(4000) = NULL,
  17824. -- Job name, used in scripting.
  17825. @agent_name sysname = NULL,
  17826. @merge_jobid binary(16) = NULL OUTPUT,
  17827. -- Agent offload
  17828. @offloadagent bit = 0,
  17829. @offloadserver sysname = NULL
  17830. as
  17831.  
  17832.     set nocount on
  17833.  
  17834.     declare @publisher_id smallint
  17835.     declare @subscriber_id smallint
  17836.     declare @publication_id int
  17837.     declare @retcode int
  17838.  
  17839.     -- default values 
  17840.     declare @flushfrequency int 
  17841.     declare @frequencytype int
  17842.     declare @frequencyinterval int 
  17843.     declare @frequencyrelativeinterval int
  17844.     declare @frequencyrecurrencefactor int 
  17845.     declare @frequencysubday int 
  17846.     declare @frequencysubdayinterval int
  17847.     declare @activestarttimeofday int
  17848.     declare @activeendtimeofday int
  17849.     declare @activestartdate int 
  17850.     declare @activeenddate int 
  17851.     declare @push int
  17852.     declare @local_job bit
  17853.     declare @thirdparty_flag bit
  17854.  
  17855.     select @push = 0
  17856.  
  17857.     -- Check if publisher is a defined as a distribution publisher in the current database
  17858.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  17859.     if @retcode <> 0
  17860.     begin
  17861.         return(1)
  17862.     end
  17863.  
  17864.     -- Get the publication information 
  17865.     select @publication_id = publication_id,
  17866.         @thirdparty_flag = thirdparty_flag from 
  17867.         MSpublications where 
  17868.         publisher_id = @publisher_id and
  17869.         publisher_db = @publisher_db and
  17870.         publication = @publication
  17871.     if @publication_id is NULL
  17872.     begin
  17873.         raiserror (20026, 11, -1, @publication)
  17874.         return (1)
  17875.     end
  17876.  
  17877.     -- Get subscriber info
  17878.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  17879.  
  17880.     -- Make sure subscription does not already exist
  17881.     if exists (select * from MSmerge_subscriptions where 
  17882.         publisher_id = @publisher_id and 
  17883.         publisher_db = @publisher_db and 
  17884.         publication_id = @publication_id and
  17885.         subscriber_id = @subscriber_id and
  17886.         subscriber_db = @subscriber_db)
  17887.     begin
  17888.         if @thirdparty_flag = 1
  17889.         begin
  17890.             raiserror (14058, 16, -1)
  17891.             return(1)
  17892.         end
  17893.         else
  17894.         begin
  17895.             exec @retcode = dbo.sp_MSdrop_merge_subscription 
  17896.                 @publisher = @publisher,
  17897.                 @publisher_db = @publisher_db,
  17898.                 @publication = @publication,
  17899.                 @subscriber = @subscriber,
  17900.                 @subscriber_db = @subscriber_db,
  17901.                 @subscription_type  = @subscription_type
  17902.             if @retcode <> 0 or @@error <> 0
  17903.             begin
  17904.                 return (1)
  17905.             end
  17906.         end
  17907.     end
  17908.  
  17909.     --Get default task parameter values from MSsubscriber_info 
  17910.     
  17911.     select @frequencytype = frequency_type,
  17912.         @frequencyinterval = frequency_interval,
  17913.         @frequencyrelativeinterval = frequency_relative_interval,
  17914.         @frequencyrecurrencefactor = frequency_recurrence_factor,
  17915.         @frequencysubday = frequency_subday,
  17916.         @frequencysubdayinterval = frequency_subday_interval,
  17917.         @activestarttimeofday = active_start_time_of_day,
  17918.         @activeendtimeofday = active_end_time_of_day,
  17919.         @activestartdate = active_start_date,
  17920.         @activeenddate = active_end_date
  17921.     from MSsubscriber_schedule 
  17922.     where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 1
  17923.  
  17924.     if @frequency_type is null
  17925.         select @frequency_type = @frequencytype
  17926.  
  17927.     if @frequency_interval  is null
  17928.         select  @frequency_interval = @frequencyinterval
  17929.  
  17930.     if @frequency_relative_interval is null
  17931.         select  @frequency_relative_interval = @frequencyrelativeinterval
  17932.  
  17933.     if @frequency_recurrence_factor is null
  17934.         select  @frequency_recurrence_factor = @frequencyrecurrencefactor
  17935.  
  17936.     if @frequency_subday is null
  17937.         select  @frequency_subday = @frequencysubday
  17938.  
  17939.     if @frequency_subday_interval is null
  17940.         select  @frequency_subday_interval = @frequencysubdayinterval
  17941.  
  17942.     if @active_start_time_of_day is null
  17943.         select  @active_start_time_of_day = @activestarttimeofday
  17944.  
  17945.     if @active_end_time_of_day is null
  17946.         select  @active_end_time_of_day = @activeendtimeofday
  17947.  
  17948.     if @active_start_date is null
  17949.         select  @active_start_date = @activestartdate
  17950.  
  17951.     if @active_end_date is null
  17952.         select  @active_end_date = @activeenddate
  17953.  
  17954.     begin transaction 
  17955.  
  17956.     -- If push and agent name is not passed in, create local job.
  17957.     if @subscription_type = @push
  17958.         select @local_job = 1
  17959.     else
  17960.         select @local_job = 0
  17961.  
  17962.     insert into MSmerge_subscriptions values (@publisher_id, @publisher_db, @publication_id,
  17963.         @subscriber_id, @subscriber_db, @subscription_type, @sync_type, @status, 
  17964.         getdate())  -- need to store GUID?
  17965.     if @@error <> 0
  17966.     begin
  17967.         goto FAILURE
  17968.     end
  17969.  
  17970.     -- Create Merge Agent
  17971.     exec @retcode = dbo.sp_MSadd_merge_agent
  17972.         @name = @agent_name, 
  17973.         @publisher = @publisher,
  17974.         @publisher_db = @publisher_db,
  17975.         @publication = @publication,
  17976.         @subscriber = @subscriber,
  17977.         @subscriber_db = @subscriber_db,
  17978.         @local_job = @local_job,
  17979.         @frequency_type  = @frequency_type,                         
  17980.         @frequency_interval = @frequency_interval, 
  17981.         @frequency_relative_interval = @frequency_relative_interval, 
  17982.         @frequency_recurrence_factor = @frequency_recurrence_factor, 
  17983.         @frequency_subday = @frequency_subday, 
  17984.         @frequency_subday_interval = @frequency_subday_interval,
  17985.         @active_start_time_of_day = @active_start_time_of_day, 
  17986.         @active_end_time_of_day = @active_end_time_of_day,         
  17987.         @active_start_date = @active_start_date, 
  17988.         @active_end_date = @active_end_date,
  17989.         @optional_command_line = @optional_command_line,
  17990.         @merge_jobid = @merge_jobid OUTPUT,
  17991.         @offloadagent = @offloadagent,
  17992.         @offloadserver = @offloadserver,
  17993.         @subscription_type = @subscription_type
  17994.  
  17995.     if @retcode <> 0 or @@error <> 0
  17996.     begin
  17997.         goto FAILURE
  17998.     end
  17999.     
  18000.     commit transaction
  18001.     return (0)
  18002.  
  18003. FAILURE:
  18004.     /* UNDONE : This code is specific to 6.X nested transaction semantics */
  18005.     if @@TRANCOUNT = 1 
  18006.         ROLLBACK TRANSACTION 
  18007.     else
  18008.         COMMIT TRANSACTION 
  18009.     RETURN (1)
  18010.     
  18011. GO
  18012.  
  18013. raiserror(15339,-1,-1,'sp_MSenum_merge_subscriptions')
  18014. GO
  18015. create procedure sp_MSenum_merge_subscriptions
  18016. @publisher sysname,
  18017. @publisher_db sysname,
  18018. @publication sysname,
  18019. @exclude_anonymous bit = 0
  18020.  
  18021. as
  18022.  
  18023.     declare @subscriber sysname
  18024.     declare @subscriber_db sysname
  18025.     declare @subscriber_name sysname
  18026.     declare @type int
  18027.     declare @status int
  18028.     declare @agent_name nvarchar(100)
  18029.     declare @subscriber_id smallint
  18030.     declare @publisher_id smallint
  18031.     declare @start_time nvarchar(24)
  18032.     declare @time nvarchar(24)
  18033.     declare @duration int
  18034.     declare @comments nvarchar(255)
  18035.     declare @delivery_rate float
  18036.     declare @error_id int
  18037.     declare @publication_id int
  18038.     declare @publisher_insertcount int
  18039.     declare @publisher_updatecount int
  18040.     declare @publisher_deletecount int
  18041.     declare @publisher_conflictcount int
  18042.     declare @subscriber_insertcount int
  18043.     declare @subscriber_updatecount int
  18044.     declare @subscriber_deletecount int
  18045.     declare @subscriber_conflictcount int
  18046.     declare @job_id binary(16)
  18047.     declare @local_job bit
  18048.     declare @profile_id int
  18049.     declare @agent_id int
  18050.     declare @last_timestamp binary(8)
  18051.     declare @offload_enabled bit
  18052.     declare @offload_server sysname
  18053.         ,@subscriber_type tinyint
  18054.  
  18055.     set nocount on
  18056.  
  18057.  
  18058.     select @publisher_id = srvid from master..sysservers where
  18059.        UPPER(srvname) = UPPER(@publisher)
  18060.  
  18061.     select @publication_id = publication_id from MSpublications  where 
  18062.             publisher_id = @publisher_id and
  18063.             publisher_db = @publisher_db and
  18064.             publication = @publication and
  18065.             publication_type = 2 -- Merge 
  18066.  
  18067.     create table #merge_subscriptions (subscriber sysname NOT NULL,  status int NOT NULL, 
  18068.         subscriber_db sysname NOT NULL, type int NOT NULL, agent_name nvarchar(100) NOT NULL, last_action nvarchar(255) NULL, 
  18069.         action_time nvarchar(24) NULL, start_time nvarchar(24) NULL, duration int NULL, 
  18070.         delivery_rate float NULL,
  18071.         publisher_insertcount int NULL, publisher_updatecount int NULL, publisher_deletecount int NULL,
  18072.         publisher_conficts int NULL, 
  18073.         subscriber_insertcount int NULL, subscriber_updatecount int NULL, subscriber_deletecount int NULL,
  18074.         subscriber_conficts int NULL, error_id int NULL, job_id binary(16) NULL,
  18075.         local_job bit NULL, profile_id int NOT NULL, 
  18076.         agent_id int NOT NULL, last_timestamp binary(8) NOT NULL, offload_enabled bit NOT NULL, 
  18077.         offload_server sysname NULL, subscriber_type tinyint NULL)
  18078.     
  18079.     -- This is to force all queries to return rows ordered by job_id
  18080.     create unique clustered index ucmerge_subscriptions ON #merge_subscriptions (agent_id)
  18081.  
  18082.     declare hC CURSOR LOCAL FAST_FORWARD FOR select subscriber_id, subscriber_db, name, job_id, local_job, profile_id, id, subscriber_name,
  18083.                                                     offload_enabled, offload_server
  18084.                                 from MSmerge_agents 
  18085.                                  where publisher_id = @publisher_id and publisher_db = @publisher_db and publication = @publication  and 
  18086.                                     (@exclude_anonymous = 0 or subscriber_name is null)
  18087.                             for read only
  18088.     open hC
  18089.     fetch hC into  @subscriber_id, @subscriber_db, @agent_name, @job_id, @local_job, @profile_id, @agent_id, @subscriber_name, @offload_enabled,
  18090.                    @offload_server
  18091.     while (@@fetch_status <> -1)
  18092.     begin
  18093.  
  18094.         if @subscriber_name is not NULL 
  18095.             begin
  18096.                 select @subscriber = @subscriber_name
  18097.                 select @subscriber_db = @subscriber_db + '-' + convert(nvarchar(4), @agent_id)
  18098.                 select @type = 2   --anonymous subscription
  18099.             end
  18100.         else
  18101.             begin
  18102.                 select @subscriber = srvname from master..sysservers where srvid=@subscriber_id
  18103.                 select @type = subscription_type from MSmerge_subscriptions 
  18104.                     where publisher_id = @publisher_id and
  18105.                         publisher_db = @publisher_db and
  18106.                         publication_id = @publication_id and
  18107.                         subscriber_id = @subscriber_id and
  18108.                         subscriber_db = @subscriber_db
  18109.                 select @subscriber_type = type from MSsubscriber_info where
  18110.                     UPPER(publisher) = UPPER(@publisher) and
  18111.                     UPPER(subscriber) = UPPER(@subscriber)
  18112.             end
  18113.             
  18114.         -- Get the status of the agent
  18115.         select @status = 0 
  18116.         select  @start_time = NULL,
  18117.             @time = NULL, 
  18118.             @duration = NULL, 
  18119.             @comments = NULL,
  18120.             @publisher_insertcount = NULL,
  18121.             @publisher_deletecount = NULL,
  18122.             @publisher_updatecount =  NULL,
  18123.             @publisher_conflictcount =  NULL,
  18124.             @subscriber_insertcount = NULL,
  18125.             @subscriber_deletecount = NULL,
  18126.             @subscriber_updatecount =  NULL,
  18127.             @subscriber_conflictcount =  NULL,
  18128.             @delivery_rate = NULL, 
  18129.             @error_id = NULL,
  18130.             @last_timestamp = 0x00000000
  18131.                 
  18132.         select @status = isnull(runstatus,0),
  18133.             @start_time = convert(nvarchar(12), start_time, 112) +
  18134.                           substring(convert(nvarchar(24), start_time, 121), 11, 13),
  18135.             @time = convert(nvarchar(12), time, 112) +
  18136.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  18137.             @duration = duration, 
  18138.             @comments = comments,
  18139.             @publisher_insertcount = publisher_insertcount,
  18140.             @publisher_deletecount = publisher_deletecount,
  18141.             @publisher_updatecount =  publisher_updatecount,
  18142.             @publisher_conflictcount =  publisher_conflictcount,
  18143.             @subscriber_insertcount = subscriber_insertcount,
  18144.             @subscriber_deletecount = subscriber_deletecount,
  18145.             @subscriber_updatecount =  subscriber_updatecount,
  18146.             @subscriber_conflictcount =  subscriber_conflictcount,
  18147.             -- Note: return average rate here !!! delivery_rate column is current rate
  18148.             @delivery_rate = 
  18149.                 case    when duration <> 0 then 
  18150.                             (publisher_insertcount + publisher_updatecount +
  18151.                             publisher_deletecount + subscriber_insertcount + 
  18152.                             subscriber_updatecount + subscriber_deletecount)/duration
  18153.                         when duration = 0 then 0
  18154.                 end, 
  18155.             @error_id = error_id, @last_timestamp = timestamp
  18156.             from MSmerge_history
  18157.             where
  18158.                 agent_id = @agent_id and
  18159.                 timestamp = (select max(timestamp) from MSmerge_history 
  18160.                     where agent_id = @agent_id)
  18161. /* Not currently working Build 351
  18162.                 timestamp = (select top 1 timestamp from MSmerge_history 
  18163.                     where agent_id = @agent_id
  18164.                     order by timestamp DESC) 
  18165. */
  18166.         
  18167.             insert into #merge_subscriptions values ( @subscriber, @status, @subscriber_db,
  18168.                 @type, @agent_name, @comments, @time, @start_time, @duration,
  18169.                 @delivery_rate, 
  18170.                 @publisher_insertcount, @publisher_updatecount, @publisher_deletecount, 
  18171.                 @publisher_conflictcount,
  18172.                 @subscriber_insertcount, @subscriber_updatecount, @subscriber_deletecount, 
  18173.                 @subscriber_conflictcount,
  18174.                 @error_id, @job_id, @local_job, @profile_id, @agent_id, @last_timestamp,
  18175.                 @offload_enabled, @offload_server, @subscriber_type)
  18176.         
  18177.  
  18178.         fetch hC into  @subscriber_id, @subscriber_db, @agent_name, @job_id, @local_job, @profile_id, @agent_id, @subscriber_name,
  18179.                        @offload_enabled, @offload_server
  18180.       end
  18181.  
  18182.     select * from #merge_subscriptions order by job_id asc
  18183.  
  18184.     drop table #merge_subscriptions
  18185.     close hC
  18186.     deallocate hC
  18187.  
  18188. go
  18189.  
  18190. raiserror(15339,-1,-1,'sp_update_agent_profile')
  18191. GO
  18192.  
  18193. -- Update the profile for an agent
  18194. CREATE PROCEDURE sp_update_agent_profile (
  18195.     @agent_type     int,
  18196.     @agent_id       int,
  18197.     @profile_id int
  18198. )
  18199. AS
  18200.     SET NOCOUNT ON
  18201.  
  18202.     DECLARE @proc               nvarchar(255)
  18203.  
  18204.     DECLARE @snapshot_type          int
  18205.     DECLARE @logreader_type         int
  18206.     DECLARE @distribution_type      int
  18207.     DECLARE @merge_type         int
  18208.     DECLARE    @qreader_type            int
  18209.  
  18210.     SELECT @snapshot_type = 1
  18211.     SELECT @logreader_type = 2
  18212.     SELECT @distribution_type = 3
  18213.     SELECT @merge_type = 4
  18214.     SELECT @qreader_type = 9
  18215.  
  18216.     IF @agent_type NOT IN (@snapshot_type, @logreader_type, @distribution_type, @merge_type, @qreader_type)
  18217.         RETURN (1) 
  18218.  
  18219.     /* The profile must be defined for the agent type in MSagent_profiles table */
  18220.     IF NOT EXISTS ( select * from msdb..MSagent_profiles
  18221.             where profile_id = @profile_id
  18222.             and agent_type = @agent_type )
  18223.         RETURN (1)
  18224.     
  18225.     -- The system 'SkipErrors' profile is for sql subscribers only.
  18226.     if @distribution_type = @agent_type and @profile_id = 14
  18227.     begin
  18228.         declare @subscriber_id int, @publisher_id int
  18229.         select top 1 @publisher_id = publisher_id, @subscriber_id = subscriber_id from
  18230.             MSsubscriptions where agent_id = @agent_id
  18231.         declare @subscriber sysname, @publisher sysname
  18232.         select @publisher = srvname from master..sysservers where srvid = @publisher_id
  18233.         select @subscriber = srvname from master..sysservers where srvid = @subscriber_id
  18234.  
  18235.         -- Use 'exists' not 'not exists' to take care null @publisher or @subscriber
  18236.         if exists (select * from MSsubscriber_info where
  18237.             upper(publisher) = upper(@publisher) and
  18238.             upper(subscriber) = upper(@subscriber) and
  18239.             type <> 0)
  18240.         begin
  18241.             raiserror(20603, 16, -1)
  18242.             return 1
  18243.         end
  18244.     end
  18245.     
  18246.     SELECT @proc = 'UPDATE ' +
  18247.         CASE @agent_type
  18248.            WHEN @snapshot_type THEN 'MSsnapshot_agents'
  18249.            WHEN @logreader_type THEN 'MSlogreader_agents'
  18250.            WHEN @distribution_type THEN 'MSdistribution_agents'
  18251.            WHEN @merge_type THEN 'MSmerge_agents'
  18252.            WHEN @qreader_type THEN 'MSqreader_agents'
  18253.         END
  18254.         + ' SET profile_id = ' + convert(nvarchar(10), @profile_id)
  18255.         + ' WHERE id = ' + convert(nvarchar(10), @agent_id)
  18256.  
  18257.     EXECUTE (@proc)
  18258.  
  18259.     IF @@ERROR <> 0 
  18260.         RETURN (1)
  18261. GO
  18262.  
  18263.  
  18264. raiserror(15339,-1,-1,'sp_MSprofile_in_use')
  18265. GO
  18266.  
  18267. CREATE PROCEDURE sp_MSprofile_in_use (
  18268.     @tablename          nvarchar(255),
  18269.     @profile_id int
  18270. )
  18271. AS
  18272.     DECLARE @usage_count int
  18273.  
  18274.     IF @tablename IS NULL OR @profile_id IS NULL
  18275.         return 1 ;
  18276.  
  18277.     IF @tablename = 'MSsnapshot_agents'
  18278.         SELECT @usage_count = count(*) FROM MSsnapshot_agents
  18279.         WHERE profile_id = @profile_id
  18280.     ELSE IF @tablename = 'MSlogreader_agents'
  18281.             SELECT @usage_count = count(*) FROM MSlogreader_agents
  18282.             WHERE profile_id = @profile_id
  18283.         ELSE IF @tablename = 'MSdistribution_agents'
  18284.                 SELECT @usage_count = count(*) FROM MSdistribution_agents
  18285.                 WHERE profile_id = @profile_id
  18286.             ELSE IF @tablename = 'MSmerge_agents'
  18287.                     SELECT @usage_count = count(*) FROM MSmerge_agents 
  18288.                     WHERE profile_id = @profile_id
  18289.                 ELSE 
  18290.                     SELECT @usage_count = 0
  18291.  
  18292.     IF @usage_count = 0
  18293.         RETURN -1
  18294.     ELSE
  18295.         RETURN 0
  18296. GO
  18297.  
  18298.  
  18299. raiserror(15339,-1,-1,'sp_MSreset_subscription')
  18300. GO
  18301. CREATE PROCEDURE sp_MSreset_subscription (
  18302.     @publisher sysname,
  18303.     @publisher_db sysname,
  18304.     @publication sysname,  
  18305.     @subscriber sysname,
  18306.     @subscriber_db sysname,
  18307.     @subscription_type int  -- have to have it to identify a distribution agent.
  18308. ) AS
  18309.  
  18310.  
  18311.     SET NOCOUNT ON
  18312.  
  18313.     /*
  18314.     ** Declarations.
  18315.     */
  18316.     DECLARE @retcode            int
  18317.     DECLARE @publisher_id       smallint
  18318.     DECLARE @subscriber_id      smallint
  18319.     DECLARE @virtual            smallint
  18320.     declare @publication_id        int
  18321.     declare @immediate_sync        bit
  18322.  
  18323.  
  18324.     /*
  18325.     ** Initializations
  18326.     */
  18327.     select @virtual = -1
  18328.  
  18329.     select @publisher_id = srvid from master..sysservers where 
  18330.         UPPER(srvname) = UPPER(@publisher)
  18331.  
  18332.     select @subscriber_id = srvid from master..sysservers where 
  18333.         UPPER(srvname) = UPPER(@subscriber) 
  18334.  
  18335.     select @publication_id = publication_id, @immediate_sync = immediate_sync
  18336.         from MSpublications where
  18337.         publisher_id = @publisher_id AND
  18338.         publisher_db = @publisher_db AND
  18339.         publication = @publication
  18340.  
  18341.     if @subscriber is NULL
  18342.         select @subscriber_id = @virtual
  18343.  
  18344.     -- No need to have 2 updates in one transaction.
  18345.     if @immediate_sync = 1
  18346.     begin
  18347.         UPDATE MSdistribution_agents SET subscription_guid = newid()
  18348.             WHERE
  18349.             publisher_id = @publisher_id AND
  18350.             publisher_db = @publisher_db AND
  18351.             publication = @publication and
  18352.             subscriber_id = @subscriber_id and
  18353.             subscriber_db = @subscriber_db and
  18354.             subscription_type = @subscription_type
  18355.  
  18356.         IF @@ERROR <> 0
  18357.             GOTO UNDO
  18358.     end
  18359.  
  18360.     UPDATE MSsubscriptions set subscription_time = getdate() 
  18361.         WHERE
  18362.         publisher_id = @publisher_id AND
  18363.         publisher_db = @publisher_db AND
  18364.         publication_id = @publication_id and
  18365.         subscriber_id = @subscriber_id and
  18366.         subscriber_db = @subscriber_db and
  18367.         subscription_type = @subscription_type
  18368.  
  18369.     IF @@ERROR <> 0
  18370.         GOTO UNDO
  18371.  
  18372.     RETURN(0)
  18373.  
  18374. UNDO:
  18375.     return(1)
  18376. GO
  18377.  
  18378. raiserror(15339,-1,-1,'sp_MSget_subscription_guid')
  18379. GO
  18380. CREATE PROCEDURE sp_MSget_subscription_guid (
  18381. @agent_id int )
  18382. as
  18383. begin
  18384.     set nocount on
  18385.  
  18386.     -- You need to make change to sp_MShelp_distribution_agentid when changing
  18387.     -- this.    
  18388.     -- Get subscription_guid
  18389.     select a1.subscription_guid
  18390.     from MSdistribution_agents a1
  18391.     where
  18392.     -- for non anonymous agents
  18393.     ((a1.virtual_agent_id is null and a1.id = @agent_id) or
  18394.     (   -- for anonymous agents
  18395.         a1.id = (select virtual_agent_id from MSdistribution_agents a2 where
  18396.             a2.id = @agent_id)) -- virtual account
  18397.     ) 
  18398. end            
  18399. GO
  18400.  
  18401.  
  18402. raiserror(15339,-1,-1,'sp_MSreset_subscription_seqno')
  18403. GO
  18404. CREATE PROCEDURE sp_MSreset_subscription_seqno (
  18405. @agent_id int,
  18406. @get_snapshot bit )
  18407. as
  18408.     set nocount on
  18409.  
  18410.     declare @publication_id int
  18411.     declare @sub_agent_id int
  18412.     declare @virtual_anonymous smallint
  18413.     declare @virtual smallint
  18414.     declare @retcode int
  18415.     declare @automatic tinyint
  18416.  
  18417.     select @automatic = 1
  18418.     select @virtual = -1
  18419.     select @virtual_anonymous = -2
  18420.  
  18421.     -- Security Check
  18422.     exec @retcode = dbo.sp_MScheck_pull_access
  18423.         @agent_id = @agent_id,
  18424.         @agent_type = 0 -- distribution agent
  18425.     if @@error <> 0 or @retcode <> 0
  18426.         return (1)
  18427.  
  18428.     -- Get version agent_id
  18429.     select top 1 @sub_agent_id = s2.agent_id from MSsubscriptions s1,
  18430.         MSsubscriptions s2 where
  18431.         s1.publisher_id = s2.publisher_id and
  18432.         s1.publisher_db = s2.publisher_db and
  18433.         s1.publication_id = s2.publication_id and
  18434.         s1.agent_id = @agent_id and
  18435.         s2.subscriber_id = 
  18436.             case @get_snapshot when 0 
  18437.                 then @virtual_anonymous
  18438.                 else @virtual
  18439.             end 
  18440.     
  18441.     -- If there are no virtual subscriptions defined. Don't reset.
  18442.     -- This might happen when the distribution agent tries to 
  18443.     -- reset an subscription on a non immediate_sync publication 
  18444.     -- (this can
  18445.     -- only happen when the publication is changed from immediate_sync to non
  18446.     -- immdiate_sync after the distribution agent has queried the immediate_sync
  18447.     -- property)
  18448.     if @sub_agent_id = 0
  18449.         return 0
  18450.  
  18451.     -- 'no_sync' subscriptions are handled differently
  18452.     if exists (select * from MSsubscriptions where agent_id = @agent_id and 
  18453.         sync_type <> @automatic)
  18454.     begin
  18455.         -- If @get_snapshot = 0, the distribution agent is process the attached
  18456.         -- subscription for the first time. Set subscription_seqno to zero so that
  18457.         -- all changes that are not in the subscription copy will be picked up.
  18458.         -- Otherwise, do noting.
  18459.         if @get_snapshot = 0
  18460.         begin
  18461.             update MSsubscriptions  set 
  18462.                 -- Use current date rather than virtual sub date for the
  18463.                 -- calculation in cleanup 
  18464.                 subscription_time = getdate(),
  18465.                 -- lsn should be ten bytes long. We will not be here
  18466.                 -- if the publisher is 6.x since 6x publisher does not
  18467.                 -- support immediate_sync (thus does not support subscription copy as well)
  18468.                 subscription_seqno = 0x00000000000000000000,
  18469.                 publisher_seqno = 0x00000000000000000000,
  18470.                 ss_cplt_seqno = 0x00000000000000000000
  18471.                 from MSsubscriptions rs1 where
  18472.                     agent_id = @agent_id 
  18473.         end        
  18474.         return 0
  18475.     end
  18476.  
  18477.     -- Reset the subscription statue to be that of the virtual_anonymous subscription.
  18478.     -- Thus, only the snapshot transactions that are later than the subscriber transaction
  18479.     -- timestamp will be picked up (i.e., new article or schema change article.)
  18480.     update MSsubscriptions  set 
  18481.         snapshot_seqno_flag =  
  18482.             (select subscription_seqno from MSsubscriptions rs2
  18483.                 where
  18484.                 rs2.agent_id = @sub_agent_id and
  18485.                 rs2.article_id = rs1.article_id),
  18486.         status =    
  18487.             (select status from MSsubscriptions rs2
  18488.                 where
  18489.                 rs2.agent_id = @sub_agent_id and
  18490.                 rs2.article_id = rs1.article_id),
  18491.         -- Use current date rather than virtual sub date for the
  18492.         -- calculation in cleanup 
  18493.         subscription_time = getdate(),
  18494.         subscription_seqno = 
  18495.             (select subscription_seqno from MSsubscriptions rs2
  18496.                 where
  18497.                 rs2.agent_id = @sub_agent_id and
  18498.                 rs2.article_id = rs1.article_id),
  18499.         publisher_seqno = 
  18500.             (select publisher_seqno from MSsubscriptions rs2
  18501.                 where
  18502.                 rs2.agent_id = @sub_agent_id and
  18503.                 rs2.article_id = rs1.article_id),
  18504.         ss_cplt_seqno = 
  18505.             (select ss_cplt_seqno from MSsubscriptions rs2
  18506.                 where
  18507.                 rs2.agent_id = @sub_agent_id and
  18508.                 rs2.article_id = rs1.article_id)
  18509.         from MSsubscriptions rs1 where
  18510.             agent_id = @agent_id
  18511.         
  18512.     if @@ERROR <> 0
  18513.         return 1
  18514. GO
  18515.  
  18516.  
  18517. raiserror(15339,-1,-1,'sp_MShelp_profile')
  18518. GO
  18519.  
  18520. CREATE PROCEDURE sp_MShelp_profile (        
  18521.     @agent_id   int,
  18522.     @agent_type int,
  18523.     @profile_name sysname = NULL
  18524. )
  18525. as
  18526.     declare @profile_id int
  18527.     declare @snapshot_type int
  18528.     declare @logreader_type int
  18529.     declare @distribution_type int
  18530.     declare @merge_type int
  18531.     declare @qreader_type int
  18532.  
  18533.     select @snapshot_type = 1
  18534.     select @logreader_type = 2
  18535.     select @distribution_type = 3
  18536.     select @merge_type = 4
  18537.     select @qreader_type = 9
  18538.  
  18539.     select @profile_id = NULL
  18540.  
  18541.     if (@profile_name is not null) and (rtrim(ltrim(@profile_name)) <> '')
  18542.     begin
  18543.         select @profile_id = profile_id from msdb..MSagent_profiles where
  18544.             agent_type = @agent_type and profile_name = @profile_name
  18545.  
  18546.         /* raise error if profile not found */
  18547.         if (@profile_id is null)
  18548.         begin
  18549.             raiserror(21123, 16, -1, @profile_name)
  18550.             return (1)
  18551.         end
  18552.     end
  18553.     
  18554.     -- if profile name not specified, use default.
  18555.     if (@profile_id is null)
  18556.     begin
  18557.         if @agent_type = @snapshot_type 
  18558.         begin
  18559.             if @agent_id = 0
  18560.                 select @profile_id = profile_id from msdb..MSagent_profiles where
  18561.                     agent_type = @agent_type and def_profile = 1
  18562.             else
  18563.                 select @profile_id = profile_id from MSsnapshot_agents
  18564.                     where id = @agent_id
  18565.         end
  18566.         else if @agent_type = @logreader_type
  18567.         begin
  18568.             if @agent_id = 0
  18569.                 select @profile_id = profile_id from msdb..MSagent_profiles where
  18570.                     agent_type = @agent_type and def_profile = 1
  18571.             else
  18572.                 select @profile_id = profile_id from MSlogreader_agents
  18573.                     where id = @agent_id
  18574.         end
  18575.         else if @agent_type = @distribution_type
  18576.         begin
  18577.             if @agent_id = 0
  18578.                 select @profile_id = profile_id from msdb..MSagent_profiles where
  18579.                     agent_type = @agent_type and def_profile = 1
  18580.             else
  18581.                 select @profile_id = profile_id from MSdistribution_agents
  18582.                     where id = @agent_id
  18583.         end
  18584.         else if @agent_type = @merge_type
  18585.         begin
  18586.             if @agent_id = 0
  18587.                 select @profile_id = profile_id from msdb..MSagent_profiles where
  18588.                     agent_type = @agent_type and def_profile = 1
  18589.             else
  18590.                 select @profile_id = profile_id from MSmerge_agents
  18591.                     where id = @agent_id
  18592.         end
  18593.         else if @agent_type = @qreader_type
  18594.         begin
  18595.             if @agent_id = 0
  18596.                 select @profile_id = profile_id from msdb..MSagent_profiles where
  18597.                     agent_type = @agent_type and def_profile = 1
  18598.             else
  18599.                 select @profile_id = profile_id from MSqreader_agents
  18600.                     where id = @agent_id
  18601.         end
  18602.     end
  18603.     
  18604.     select profile_id, parameter_name, value 
  18605.         from msdb..MSagent_parameters
  18606.         where profile_id = @profile_id
  18607. GO
  18608.  
  18609. raiserror(15339,-1,-1,'sp_MShelp_snapshot_agentid')
  18610. GO
  18611.  
  18612. CREATE PROCEDURE sp_MShelp_snapshot_agentid (
  18613.     @publisher_id       smallint,
  18614.     @publisher_db       sysname,
  18615.     @publication        sysname,
  18616.     @job_id             binary(16) = NULL
  18617. )
  18618. AS
  18619.     set nocount on
  18620.     declare @retcode int
  18621.     declare @publisher sysname
  18622.     declare @description nvarchar(255)
  18623.  
  18624.     -- Check if agent exists, if not and there is an 6.x tasks then create one
  18625.     if @publication is not null and @publication <> '' and not exists (select * from MSsnapshot_agents where
  18626.             publisher_id = @publisher_id and
  18627.             publisher_db = @publisher_db and
  18628.             publication = @publication)
  18629.     begin
  18630.         -- Do it only if the agent name is valid. It will be the case if
  18631.         -- the agent is launched by SQL Server Agent
  18632.         if exists (select * from msdb..sysjobs_view where
  18633.             job_id = @job_id)
  18634.         begin
  18635.             select @publisher = srvname from master..sysservers where srvid = @publisher_id
  18636.             begin tran
  18637.             exec @retcode = dbo.sp_MSadd_snapshot_agent
  18638.                 @publisher = @publisher, 
  18639.                 @publisher_db = @publisher_db,
  18640.                 @publication = @publication,
  18641.                 @local_job = 1,
  18642.                 @job_existing = 1,
  18643.                 @snapshot_jobid = @job_id
  18644.             if @@ERROR<> 0 or @retcode <> 0
  18645.                 goto UNDO
  18646.  
  18647.             -- Add a publication definition so it shows up in monitoring procs
  18648.             set @description = formatmessage(20555)
  18649.             exec @retcode = dbo.sp_MSadd_publication
  18650.                 @publisher = @publisher,
  18651.                 @publisher_db = @publisher_db,
  18652.                 @publication = @publication,
  18653.                 @publication_type = 1,              -- Make all 6.x pubs transactional
  18654.                 @description = @description     -- 6.x publication description
  18655.  
  18656.             if @@ERROR<> 0 or @retcode <> 0
  18657.                 goto UNDO
  18658.             commit tran
  18659.         end
  18660.     end
  18661.  
  18662.     select id, name from MSsnapshot_agents  where 
  18663.         publisher_id = @publisher_id and
  18664.         publisher_db = @publisher_db and
  18665.         publication = @publication
  18666.  
  18667.     return(0)
  18668.  
  18669. UNDO:
  18670.     if @@TRANCOUNT = 1
  18671.         ROLLBACK TRAN
  18672.     else
  18673.         COMMIT TRAN
  18674.     return(1)
  18675. GO
  18676.  
  18677. raiserror(15339,-1,-1,'sp_MShelp_logreader_agentid')
  18678. GO
  18679.  
  18680. CREATE PROCEDURE sp_MShelp_logreader_agentid (
  18681.     @publisher_id       smallint,
  18682.     @publisher_db       sysname
  18683. )
  18684. AS
  18685.     set nocount on
  18686.     declare @retcode int
  18687.     declare @publisher sysname
  18688.     declare @job_id binary(16)
  18689.     declare @qv_package    varchar(20)
  18690.     declare @desk_top        int
  18691.     declare @license_value int
  18692.     declare @qv_value_package int
  18693.  
  18694.     select @qv_package = '845129433'
  18695.     select @license_value = 0 
  18696.     select @desk_top = 3
  18697.  
  18698.     exec @qv_value_package = master.dbo.sp_MSinstance_qv @qv_package
  18699.     if @@ERROR<>0 
  18700.     begin
  18701.         raiserror(20089, 16, -1)
  18702.         return (1)
  18703.     end
  18704.     if @qv_value_package = 1         --- 1 means desktop
  18705.         select @license_value = @desk_top   -- to be consistent with all other compenents.
  18706.     
  18707.     -- Check if agent exists, if not and there is an 6.x tasks then create one
  18708.     if not exists (select * from MSlogreader_agents where
  18709.             publisher_id = @publisher_id and
  18710.             publisher_db = @publisher_db)
  18711.     begin
  18712.         select @publisher = srvname from master..sysservers where srvid = @publisher_id
  18713.  
  18714.         -- Do it only if the agent name is valid. It will be the case if
  18715.         -- the agent is launched by SQL Server Agent
  18716.         select @job_id = id.job_id from msdb..systasks_view v,
  18717.             msdb..systaskids id
  18718.             where 
  18719.             v.server = @publisher and           
  18720.             v.databasename = @publisher_db and
  18721.             v.subsystem = 'LogReader' and
  18722.             v.id = id.task_id
  18723.  
  18724.         if @job_id is not NULL
  18725.         begin
  18726.             exec @retcode = dbo.sp_MSadd_logreader_agent
  18727.                 @publisher = @publisher, 
  18728.                 @publisher_db = @publisher_db,
  18729.                 -- 'ALL' is Used in sp_addpublication as well
  18730.                 @publication = 'ALL',
  18731.                 @local_job = 1,
  18732.                 @job_existing = 1,
  18733.                 @job_id = @job_id
  18734.             if @@ERROR<> 0 or @retcode <> 0
  18735.                 return(1)
  18736.         end
  18737.     end
  18738.   
  18739.     select id, name, @license_value from MSlogreader_agents where 
  18740.         publisher_id = @publisher_id and 
  18741.         publisher_db = @publisher_db
  18742.  
  18743.     return(0)
  18744.  
  18745. GO
  18746.  
  18747. /*
  18748. ** This procedure is to add an agent row in MSmerge_agents for an anonymous subscription,
  18749. ** if it is not already there. If it is, return the agentid and agent name for monitoring
  18750. ** purpose.
  18751. */
  18752. raiserror(15339,-1,-1,'sp_MSadd_merge_anonymous_agent')
  18753. GO
  18754.  
  18755. CREATE PROCEDURE sp_MSadd_merge_anonymous_agent (
  18756.     @publisher_id       smallint,
  18757.     @publisher_db       sysname,
  18758.     @publication        sysname,
  18759.     @subscriber_db      sysname,
  18760.     @subscriber_name    sysname,
  18761.     @subid              uniqueidentifier, 
  18762.     @first_anonymous    int        -- 0 means this is the first time for this anonymous agent being ran.
  18763. )
  18764. AS
  18765.     declare @min_valid_day  datetime
  18766.     declare @merge_type     int
  18767.     declare @profile_id     int
  18768.     declare @subscriber_id  smallint
  18769.     declare @agent_name     sysname
  18770.     declare @agent_id       int
  18771.     declare @retcode        int
  18772.     declare @publication_id int
  18773.     declare @not_exist      bit
  18774.     declare @last_status    int
  18775.     declare @last_history    datetime
  18776.     declare @merge_jobid    uniqueidentifier
  18777.     declare @by_pass        bit
  18778.     declare @retention        int
  18779.     declare @success        int
  18780.     declare @expired        int
  18781.     declare @dropped        int
  18782.     declare @allow_anonymous bit
  18783.  
  18784.     select @dropped = 0
  18785.     select @expired = 0
  18786.     select @success = 2
  18787.     select @by_pass = 0
  18788.  
  18789. /*
  18790. ** This stored procedure does not really add a job at distribution database;
  18791. ** if add a row in MSmerge_agent table for anonymous subscription for the 
  18792. ** purpose of history logging
  18793. */
  18794.  
  18795.     -- Check to see if the publication is valid and allow anonymous
  18796.     select @publication_id = publication_id, @allow_anonymous = allow_anonymous, @retention = retention from MSpublications where
  18797.         publisher_id = @publisher_id and
  18798.         publisher_db = @publisher_db and
  18799.         publication = @publication
  18800.  
  18801.     if @publication_id is null
  18802.     begin
  18803.         RAISERROR (21040, 16, -1, @publication)
  18804.         return 1
  18805.     end
  18806.  
  18807.     if @allow_anonymous = 0
  18808.     begin
  18809.         RAISERROR (21084, 16, -1, @publication)
  18810.         return 1
  18811.     end
  18812.  
  18813.     if @subscriber_name is null
  18814.         select @subscriber_name = N''
  18815.  
  18816.     if @retention is NULL or @retention =0
  18817.         select @by_pass = 1
  18818.  
  18819.     -- Security check
  18820.     exec @retcode = dbo.sp_MScheck_pull_access
  18821.         @publication_id = @publication_id, @agent_type = 1
  18822.     if @retcode <> 0 or @@error <> 0
  18823.         return (1)
  18824.  
  18825.     select @not_exist = 0
  18826.     SELECT @merge_type = 4
  18827.     select @subscriber_id = 0  -- For anonymous subscribers, ID is always 0 
  18828.  
  18829.     SELECT @profile_id = profile_id
  18830.     FROM msdb..MSagent_profiles
  18831.     WHERE agent_type = @merge_type
  18832.         AND def_profile = 1
  18833.  
  18834.     IF @profile_id IS NULL
  18835.         RETURN (1)
  18836.  
  18837.     /*
  18838.     ** This is to handle Jet only
  18839.     */
  18840.     IF @subid = '00000000-0000-0000-0000-000000000000'
  18841.     begin
  18842.         select @subid = anonymous_subid from MSmerge_agents 
  18843.                 where publisher_id=@publisher_id and 
  18844.                       publisher_db = @publisher_db and 
  18845.                       publication = @publication and 
  18846.                       subscriber_name = @subscriber_name 
  18847.                       and subscriber_db = @subscriber_db
  18848.         if @subid = '00000000-0000-0000-0000-000000000000'
  18849.             select @subid = newid()
  18850.         else
  18851.             select @first_anonymous = 1   -- for Jet, schemaversion should not be 0 in this path.
  18852.     end
  18853.          
  18854.     IF NOT EXISTS (select * from MSmerge_agents where anonymous_subid=@subid)
  18855.     begin
  18856.  
  18857.         if @first_anonymous <= 0   --only add agent entry for initial subscription only. 
  18858.         begin
  18859.             select @not_exist = 1
  18860.  
  18861.             -- Generate a job GUID for remote agents. This will be used by the UI to uniquely
  18862.             -- identify rows returned by the enums
  18863.             set @merge_jobid = newid();
  18864.  
  18865.             insert into MSmerge_agents (name, publisher_id, publisher_db, publication, 
  18866.                         subscriber_id, subscriber_db, anonymous_subid, job_id, profile_id, subscriber_name)
  18867.                     VALUES (convert(nvarchar(40), @subid), @publisher_id, @publisher_db, @publication, 
  18868.                             @subscriber_id, @subscriber_db, @subid, @merge_jobid, @profile_id, @subscriber_name)
  18869.         end
  18870.         else
  18871.             select @dropped  =1
  18872.     end
  18873.     
  18874.     select @agent_id = id, @agent_name = name from MSmerge_agents 
  18875.         where anonymous_subid=@subid  -- subid guarantees uniqueness
  18876.     
  18877.     if @by_pass = 0 --by pass the checking if retention is NULL or 0
  18878.     begin
  18879.         select @min_valid_day = dateadd(day, -@retention, getdate())
  18880.         
  18881.         select Top 1 @last_status = runstatus, @last_history = time from MSmerge_history where agent_id = @agent_id
  18882.                     order by time DESC
  18883.         if (@last_status = 6 or @last_status = 3) and EXISTS (select * from MSmerge_history where agent_id = @agent_id and runstatus = 2) 
  18884.                 select Top 1 @last_history = time from MSmerge_history where agent_id = @agent_id and runstatus = 2
  18885.                         order by time DESC    
  18886.         /*
  18887.         ** This anonymous subscription is gone for too long to be efficiently reconciled. Either reinitialization or
  18888.         ** re-deployment of this subscription is needed. Merge agent will fail.
  18889.         */
  18890.         if @last_history < @min_valid_day and @first_anonymous <> 0    --do not check for re-initialized replicas.
  18891.                     select @expired = 1
  18892.    end
  18893.  
  18894.     select @agent_id, @agent_name, @expired where @dropped = 0 --return empty result set 
  18895.         
  18896. GO
  18897.  
  18898.  
  18899. raiserror(15339,-1,-1,'sp_MShelp_merge_agentid')
  18900. GO
  18901.  
  18902. CREATE PROCEDURE sp_MShelp_merge_agentid (
  18903.     @publisher_id       smallint,
  18904.     @publisher_db       sysname,
  18905.     @publication        sysname,
  18906.     @subscriber_id      smallint,
  18907.     @subscriber_db      sysname
  18908. )
  18909. AS
  18910.     declare @publisher        sysname
  18911.     declare @subscriber        sysname
  18912.     declare @expired        int
  18913.     declare @agent_id         int
  18914.     declare @name             sysname
  18915.     declare @retention         int
  18916.     declare @last_status    int
  18917.     declare @last_history    datetime
  18918.     declare @min_valid_day     datetime
  18919.     declare @reinited         int
  18920.     declare @status         int
  18921.     declare @success        int
  18922.     declare @publication_id    int
  18923.     declare @subscriber_datasource_type int
  18924.     declare @sql_subscriber    int
  18925.     
  18926.     select @expired = 0
  18927.     select @reinited = 4
  18928.     select @success = 2
  18929.  
  18930.     select @subscriber_datasource_type = 0
  18931.     select @sql_subscriber = 0
  18932.  
  18933.     if not EXISTS (select * from MSpublications 
  18934.         where publisher_id=@publisher_id 
  18935.         and publisher_db = @publisher_db
  18936.         and publication = @publication
  18937.         and publication_type = 2) -- merge publication is gone
  18938.     begin
  18939.         select 1, @publication, 1, 0 --third column = 1 means publication is gone, making the other values meanningless.
  18940.         return (1)
  18941.     end
  18942.  
  18943.        select @publication_id = publication_id 
  18944.         from MSpublications
  18945.         where publisher_id = @publisher_id and
  18946.               publisher_db = @publisher_db and
  18947.               publication = @publication
  18948.  
  18949.     -- Get subscriber info
  18950.     select @subscriber = srvname from master..sysservers where srvid = @subscriber_id
  18951.     select @publisher = srvname from master..sysservers where srvid = @publisher_id
  18952.  
  18953.     select @subscriber_datasource_type = type
  18954.         from MSsubscriber_info 
  18955.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  18956.  
  18957.     if (@subscriber_datasource_type = @sql_subscriber)
  18958.     begin
  18959.         select @status = status from MSmerge_subscriptions where
  18960.             publisher_id = @publisher_id and 
  18961.             publisher_db = @publisher_db and 
  18962.             publication_id = @publication_id and
  18963.             subscriber_id = @subscriber_id and
  18964.             subscriber_db = @subscriber_db
  18965.  
  18966.         select @agent_id = id, @name = name from MSmerge_agents 
  18967.             where publisher_id = @publisher_id 
  18968.             and publisher_db = @publisher_db
  18969.             and publication = @publication
  18970.             and subscriber_id = @subscriber_id
  18971.             and subscriber_db = @subscriber_db
  18972.     end
  18973.     else
  18974.     begin
  18975.         select @status = status from MSmerge_subscriptions where
  18976.             publisher_id = @publisher_id and 
  18977.             publisher_db = @publisher_db and 
  18978.             publication_id = @publication_id and
  18979.             subscriber_id = @subscriber_id
  18980.  
  18981.         select @agent_id = id, @name = name from MSmerge_agents 
  18982.             where publisher_id = @publisher_id 
  18983.             and publisher_db = @publisher_db
  18984.             and publication = @publication
  18985.             and subscriber_id = @subscriber_id
  18986.     end
  18987.  
  18988.     -- Security check. Do it here to let the agent fail at the beginning
  18989.     if @agent_id is not null
  18990.     begin
  18991.         exec dbo.sp_MScheck_pull_access @agent_id = @agent_id, @agent_type = 1 -- merge agent
  18992.         select @retention = retention 
  18993.             from MSpublications 
  18994.             where publisher_id=@publisher_id and publisher_db=@publisher_db and publication=@publication 
  18995.  
  18996.         if @retention is not NULL and @retention > 0
  18997.         begin
  18998.             select @min_valid_day = dateadd(day, @retention * (-1), getdate()) 
  18999.             select Top 1 @last_status = runstatus, @last_history = time 
  19000.                     from MSmerge_history where agent_id = @agent_id
  19001.                         order by time DESC
  19002.             if @last_status = 6 and EXISTS (select * from MSmerge_history where  agent_id = @agent_id and runstatus = 2) 
  19003.                 select Top 1 @last_history = time from MSmerge_history where agent_id = @agent_id and runstatus = 2
  19004.                                 order by time DESC    
  19005.             if @last_history < @min_valid_day and @status <> @reinited
  19006.                 select @expired = 1
  19007.         end
  19008.     end
  19009.  
  19010. select @agent_id, @name, 0, @expired where @agent_id is not NULL
  19011. GO
  19012.  
  19013. raiserror(15339,-1,-1,'sp_MSdistpublisher_cleanup')
  19014. GO
  19015.  
  19016. CREATE PROCEDURE sp_MSdistpublisher_cleanup 
  19017. @publisher sysname
  19018. as
  19019.  
  19020.     set nocount on
  19021.     declare @publisher_id smallint
  19022.     declare @job_id binary(16)
  19023.     declare @retcode int
  19024.     
  19025.     -- Delete agents
  19026.     -- Get the publisher id
  19027.     -- Check if publisher is a defined as a distribution publisher in the current database
  19028.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  19029.     if @retcode <> 0
  19030.     begin
  19031.         return(1)
  19032.     end
  19033.     
  19034.     -- Dropping local jobs
  19035.     -- Use union in 'select'. Insensitive cursor will be used automatically.
  19036.     DECLARE hCagents CURSOR LOCAL FAST_FORWARD FOR
  19037.             SELECT job_id 
  19038.                 FROM MSsnapshot_agents
  19039.                 WHERE publisher_id = @publisher_id and local_job = 1
  19040.         UNION
  19041.             SELECT job_id
  19042.                 FROM MSlogreader_agents
  19043.                 WHERE publisher_id = @publisher_id and local_job = 1
  19044.         UNION
  19045.             SELECT job_id 
  19046.                 FROM MSdistribution_agents
  19047.                 WHERE publisher_id = @publisher_id and local_job = 1
  19048.         UNION
  19049.             SELECT job_id
  19050.                 FROM MSmerge_agents
  19051.                 WHERE publisher_id = @publisher_id  and local_job = 1
  19052.         FOR READ ONLY
  19053.  
  19054.     OPEN hCagents
  19055.     FETCH hCagents INTO @job_id
  19056.    
  19057.     WHILE (@@fetch_status <> -1)
  19058.     BEGIN
  19059.         IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  19060.         BEGIN
  19061.             exec @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  19062.             if @retcode <> 0 or @@error <> 0
  19063.                 return(1)
  19064.         END
  19065.         FETCH hCagents INTO @job_id 
  19066.     end
  19067.  
  19068.     -- Clean up the tables, including
  19069.     --  4 Agent tables
  19070.     --  2 subscription tables
  19071.     --  article table
  19072.     --  publication table
  19073.     --  2 subscriber table
  19074.     -- The order is to avoid breaking monitoring
  19075.  
  19076.  
  19077.     delete MSpublisher_databases where publisher_id = @publisher_id
  19078.     if @@error <> 0 
  19079.         return (1) 
  19080.  
  19081.     delete MSpublications where publisher_id = @publisher_id
  19082.     if @@error <> 0 
  19083.         return (1) 
  19084.  
  19085.     delete MSarticles where publisher_id = @publisher_id
  19086.     if @@error <> 0 
  19087.         return (1) 
  19088.  
  19089.     delete MSsubscriptions where publisher_id = @publisher_id
  19090.     if @@error <> 0 
  19091.         return (1) 
  19092.  
  19093.     delete MSmerge_subscriptions where publisher_id = @publisher_id
  19094.     if @@error <> 0 
  19095.         return (1) 
  19096.  
  19097.     delete MSsnapshot_agents where publisher_id = @publisher_id
  19098.     if @@error <> 0 
  19099.         return (1) 
  19100.     
  19101.     delete MSlogreader_agents where publisher_id = @publisher_id
  19102.     if @@error <> 0 
  19103.         return (1) 
  19104.  
  19105.     delete MSdistribution_agents where publisher_id = @publisher_id
  19106.     if @@error <> 0 
  19107.         return (1) 
  19108.  
  19109.     delete MSmerge_agents where publisher_id = @publisher_id
  19110.     if @@error <> 0 
  19111.         return (1) 
  19112.  
  19113.     delete MSsubscriber_info where UPPER(publisher) = UPPER(@publisher)
  19114.     if @@error <> 0 
  19115.         return (1) 
  19116.  
  19117.     delete MSsubscriber_schedule where UPPER(publisher) = UPPER(@publisher)
  19118.     if @@error <> 0 
  19119.         return (1) 
  19120.  
  19121.     delete MSpublication_access where not exists (select * from MSpublications p where
  19122.         p.publication_id = MSpublication_access.publication_id)
  19123.     if @@error <> 0 
  19124.         return (1) 
  19125.  
  19126.     delete MSrepl_originators where 
  19127.         not exists (select * from MSpublisher_databases p
  19128.             where p.id = MSrepl_originators.publisher_database_id )
  19129.     if @@error <> 0 
  19130.         return (1) 
  19131.  
  19132.     -- Force a refresh of the replication status temp table.
  19133.     if (select object_id('tempdb.dbo.MSreplication_agent_status')) is not NULL
  19134.         delete tempdb.dbo.MSreplication_agent_status
  19135. GO
  19136.  
  19137. raiserror(15339,-1,-1,'sp_MSenum_replication_status')
  19138. GO
  19139.  
  19140. create procedure sp_MSenum_replication_status
  19141. as
  19142.     declare @anonymous_mask int
  19143.     select @anonymous_mask = 0x80000000
  19144.  
  19145.     select 'publisher' = srvname, 'publisher_db' = sa.publisher_db, 
  19146.         'publication' = sa.publication, 'publication_type' = sa.publication_type,
  19147.         'agent_type' = 1, 'status' = runstatus, 'agent_name' = sa.name from 
  19148.         MSsnapshot_history sh1, master..sysservers, MSsnapshot_agents sa
  19149.         where 
  19150.         sh1.timestamp = (select max(timestamp) from MSsnapshot_history sh2 where
  19151.             sh2.agent_id = sa.id) and
  19152.         srvid = sa.publisher_id 
  19153.     UNION
  19154.     select srvname, sa.publisher_db, sa.publication, sa.publication_type, 
  19155.         1, 0, sa.name from 
  19156.         master..sysservers, MSsnapshot_agents sa
  19157.         where 
  19158.         srvid = sa.publisher_id and
  19159.         not exists (select * from MSsnapshot_history sh where sh.agent_id = sa.id)
  19160.     UNION
  19161.     select srvname, la.publisher_db, 'ALL', 0, 2, runstatus, la.name from
  19162.         MSlogreader_history lh1, MSlogreader_agents la, master..sysservers
  19163.         where timestamp = (select max(timestamp) from 
  19164.             MSlogreader_history lh2 where
  19165.             lh2.agent_id = la.id) and
  19166.             srvid = la.publisher_id
  19167.     UNION
  19168.     select srvname, la.publisher_db, 'ALL', 0, 2, 0, la.name from
  19169.         MSlogreader_agents la, master..sysservers
  19170.         where
  19171.             srvid = la.publisher_id and
  19172.             not exists (select * from MSlogreader_history lh where lh.agent_id = la.id)
  19173.     UNION
  19174.     select srvname, da.publisher_db, da.publication, p.publication_type, 3, runstatus, da.name from 
  19175.             MSdistribution_history dh1, master..sysservers, 
  19176.             MSdistribution_agents da, MSpublications p, MSsubscriptions s
  19177.             where timestamp = (select max(timestamp) from 
  19178.                 MSdistribution_history dh2 where
  19179.                 dh2.agent_id = da.id) and
  19180.                 srvid = da.publisher_id and
  19181.                 s.agent_id = da.id and
  19182.                 p.publication_id = s.publication_id
  19183.     UNION
  19184.     select srvname, da.publisher_db, da.publication, p.publication_type, 3, 0, da.name from 
  19185.             master..sysservers, 
  19186.             MSdistribution_agents da,
  19187.             MSpublications p,
  19188.             MSsubscriptions s
  19189.             where 
  19190.                 srvid = da.publisher_id and
  19191.                 not exists (select * from MSdistribution_history dh where dh.agent_id = da.id) and
  19192.                 s.agent_id = da.id and
  19193.                 p.publication_id = s.publication_id
  19194.     UNION    -- Load distribution dummy rows
  19195.     -- The select below will return dumplicates but it will be eliminated by union operator.
  19196.     select srvname, da.publisher_db, p.publication, p.publication_type, 
  19197.             case    when da.anonymous_agent_id is not null then 3 | @anonymous_mask
  19198.                     else 3
  19199.             end,
  19200.             runstatus, da.name from 
  19201.             MSdistribution_history dh1, master..sysservers, 
  19202.             MSdistribution_agents da, MSpublications p, MSsubscriptions s
  19203.             where timestamp = (select max(timestamp) from 
  19204.                 MSdistribution_history dh2 where
  19205.                 dh2.agent_id = da.id) and
  19206.                 srvid = da.publisher_id and
  19207.                 s.agent_id = da.id and
  19208.                 p.publication_id = s.publication_id
  19209.     UNION -- Load distrbution dummy_rows
  19210.     select srvname, da.publisher_db, p.publication, p.publication_type, 3, 0, da.name from 
  19211.             master..sysservers, 
  19212.             MSdistribution_agents da,
  19213.             MSpublications p,
  19214.             MSsubscriptions s
  19215.             where 
  19216.                 srvid = da.publisher_id and
  19217.                 not exists (select * from MSdistribution_history dh where dh.agent_id = da.id) and
  19218.                 s.agent_id = da.id and
  19219.                 p.publication_id = s.publication_id
  19220.     UNION
  19221.     select srvname, ma.publisher_db, ma.publication, 2,
  19222.         case    when ma.subscriber_name is not null then 4 | @anonymous_mask
  19223.                 else 4
  19224.         end,
  19225.         runstatus, ma.name from 
  19226.         MSmerge_history mh1, master..sysservers, MSmerge_agents ma
  19227.         where timestamp = (select max(timestamp) from
  19228.             MSmerge_history mh2 where
  19229.             mh2.agent_id = ma.id) and
  19230.             srvid = ma.publisher_id 
  19231.  
  19232.     UNION
  19233.     select srvname, ma.publisher_db, ma.publication, 2, 4, 0, ma.name from 
  19234.         master..sysservers, MSmerge_agents ma
  19235.         where 
  19236.             srvid = ma.publisher_id and
  19237.             not exists (select * from MSmerge_history mh where mh.agent_id = ma.id)
  19238.  
  19239.     UNION -- queue reader        
  19240.     select 'publisher'= @@servername, 'publisher_db' = db_name(), 'publication' = 'ALL', 
  19241.             'publication_type' = 0, 'agent_type' = 9, 'status' = runstatus, 'agent_name' = la.name 
  19242.     from MSqreader_history lh1, MSqreader_agents la
  19243.     where lh1.timestamp = 
  19244.             (select max(timestamp) from MSqreader_history lh2 
  19245.             where lh2.agent_id = la.id) 
  19246.  
  19247.     order by publisher, publisher_db, publication
  19248.  
  19249. go
  19250.  
  19251. raiserror(15339,-1,-1,'sp_MSagent_stethoscope')
  19252. GO
  19253. CREATE PROCEDURE sp_MSagent_stethoscope (
  19254.     @heartbeat_interval int = 10  --minutes
  19255. )
  19256. as
  19257. BEGIN
  19258.     declare @current_time datetime
  19259.             ,@agent_name nvarchar(100)
  19260.             ,@agent_id int
  19261.             ,@job_id binary(16)
  19262.             ,@start_time datetime
  19263.             ,@duration int
  19264.             ,@comments nvarchar(255)
  19265.             ,@publisher_id smallint
  19266.             ,@publisher sysname
  19267.             ,@publisher_db sysname
  19268.             ,@heartbeat_failure bit
  19269.             ,@snapshot_type int
  19270.             ,@logreader_type int
  19271.             ,@distribution_type int
  19272.             ,@merge_type int
  19273.             ,@qreader_type int
  19274.             ,@histverboselevel tinyint
  19275.  
  19276.     --
  19277.     -- initialize
  19278.     --
  19279.     set nocount on
  19280.     select @snapshot_type = 1
  19281.             ,@logreader_type = 2
  19282.             ,@distribution_type = 3
  19283.             ,@merge_type = 4
  19284.             ,@qreader_type = 9
  19285.             ,@heartbeat_failure = 0
  19286.             ,@current_time = getdate()
  19287.             ,@comments = formatmessage(20554, @heartbeat_interval)
  19288.  
  19289.     -- If a running snapshot agent has not logged a history message within the specified
  19290.     -- heartbeat_interval then raise a agent suspect error
  19291.     declare hC_snapshot_suspect CURSOR LOCAL FAST_FORWARD for 
  19292.         select sh1.agent_id, sh1.start_time from MSsnapshot_history sh1 where
  19293.             (sh1.runstatus = 1 or sh1.runstatus = 3 or sh1.runstatus = 4) and
  19294.             dateadd(minute, @heartbeat_interval, sh1.time) < @current_time and
  19295.             sh1.timestamp = (select max(timestamp) from MSsnapshot_history where
  19296.                 agent_id= sh1.agent_id)
  19297.         for read only
  19298.  
  19299.     open hC_snapshot_suspect
  19300.     fetch hC_snapshot_suspect into @agent_id, @start_time
  19301.     while (@@fetch_status <> -1)
  19302.     begin
  19303.  
  19304.         set @heartbeat_failure = 1
  19305.  
  19306.         -- Get the agent name
  19307.         select @agent_name = name, @job_id = job_id from MSsnapshot_agents where id = @agent_id
  19308.  
  19309.         -- Log a "No action" message on behalf of the agent
  19310.         exec dbo.sp_MSadd_snapshot_history
  19311.             @agent_id = @agent_id,
  19312.             @runstatus = 6,     -- Failure status
  19313.             @comments = @comments,
  19314.             @do_raiserror = 0
  19315.  
  19316.         fetch hC_snapshot_suspect into @agent_id, @start_time
  19317.     end
  19318.     close hC_snapshot_suspect
  19319.     deallocate hC_snapshot_suspect
  19320.  
  19321.  
  19322.     -- If a running logreader agent has not logged a history message within the specified
  19323.     -- heartbeat_interval then raise a agent suspect error
  19324.     declare hC_logreader_suspect CURSOR LOCAL FAST_FORWARD for 
  19325.         select la.id, sh1.start_time from MSlogreader_agents la, MSlogreader_history sh1 where
  19326.             (sh1.runstatus = 1 or sh1.runstatus = 3 or sh1.runstatus = 4) and
  19327.             dateadd(minute, @heartbeat_interval, sh1.time) < @current_time and
  19328.             sh1.timestamp = (select max(timestamp) from MSlogreader_history where
  19329.                 agent_id= sh1.agent_id) and
  19330.             la.id = sh1.agent_id
  19331.         for read only
  19332.  
  19333.     open hC_logreader_suspect
  19334.     fetch hC_logreader_suspect into @agent_id, @start_time
  19335.     while (@@fetch_status <> -1)
  19336.     begin
  19337.         set @heartbeat_failure = 1
  19338.  
  19339.         -- Get the agent name
  19340.         select @agent_name = name, @job_id = job_id from MSlogreader_agents where id = @agent_id
  19341.  
  19342.         -- Log a "No action" message on behalf of the agent
  19343.         select @publisher_id = publisher_id, @publisher_db = publisher_db from MSlogreader_agents where id = @agent_id
  19344.         select @publisher = srvname from master..sysservers where srvid = @publisher_id
  19345.         exec dbo.sp_MSadd_logreader_history
  19346.             @agent_id = @agent_id,
  19347.             @runstatus = 6,     -- Failure status
  19348.             @comments = @comments,
  19349.             @do_raiserror = 0
  19350.  
  19351.         fetch hC_logreader_suspect into @agent_id, @start_time
  19352.     end
  19353.     close hC_logreader_suspect
  19354.     deallocate hC_logreader_suspect
  19355.  
  19356.     -- If a running distribution agent has not logged a history message within the specified
  19357.     -- heartbeat_interval then raise a agent suspect error
  19358.     declare hC_distribution_suspect CURSOR LOCAL FAST_FORWARD for 
  19359.         select sh1.agent_id, sh1.start_time from MSdistribution_history sh1 where
  19360.             (sh1.runstatus = 1 or sh1.runstatus = 3 or sh1.runstatus = 4) and
  19361.             dateadd(minute, @heartbeat_interval, sh1.time) < @current_time and
  19362.             sh1.timestamp = (select max(timestamp) from MSdistribution_history where
  19363.                 agent_id= sh1.agent_id)
  19364.         for read only
  19365.  
  19366.     open hC_distribution_suspect
  19367.     fetch hC_distribution_suspect into @agent_id, @start_time
  19368.     while (@@fetch_status <> -1)
  19369.     begin
  19370.         -- Get the agent name
  19371.         select @heartbeat_failure = 1
  19372.         select @agent_name = name, @job_id = job_id from MSdistribution_agents where id = @agent_id
  19373.  
  19374.         -- Log a "No action" message on behalf of the agent
  19375.         exec dbo.sp_MSadd_distribution_history
  19376.             @agent_id = @agent_id,
  19377.             @runstatus = 6,     -- Failure status
  19378.             @comments = @comments,
  19379.             @do_raiserror = 0
  19380.         fetch hC_distribution_suspect into @agent_id, @start_time
  19381.     end
  19382.     close hC_distribution_suspect
  19383.     deallocate hC_distribution_suspect
  19384.  
  19385.     -- If a running merge agent has not logged a history message within the specified
  19386.     -- heartbeat_interval then raise a agent suspect error
  19387.     declare hC_merge_suspect CURSOR LOCAL FAST_FORWARD for 
  19388.         select sh1.agent_id, sh1.start_time from MSmerge_history sh1 where
  19389.             (sh1.runstatus = 1 or sh1.runstatus = 3 or sh1.runstatus = 4) and
  19390.             dateadd(minute, @heartbeat_interval, sh1.time) < @current_time and
  19391.             sh1.timestamp = (select max(timestamp) from MSmerge_history where
  19392.                 agent_id= sh1.agent_id)
  19393.         for read only
  19394.  
  19395.     open hC_merge_suspect
  19396.     fetch hC_merge_suspect into @agent_id, @start_time
  19397.     while (@@fetch_status <> -1)
  19398.     begin
  19399.         set @heartbeat_failure = 1
  19400.  
  19401.         -- Get the agent name
  19402.         select @agent_name = name, @job_id = job_id from MSmerge_agents where id = @agent_id
  19403.  
  19404.         -- Log a "No action" message on behalf of the agent
  19405.         exec dbo.sp_MSadd_merge_history
  19406.             @agent_id = @agent_id,
  19407.             @runstatus = 6,     -- Failure status
  19408.             @comments = @comments,
  19409.             @do_raiserror = 0
  19410.  
  19411.         fetch hC_merge_suspect into @agent_id, @start_time
  19412.     end
  19413.     close hC_merge_suspect
  19414.     deallocate hC_merge_suspect
  19415.  
  19416.     -- If a running queuereader agent has not logged a history message within the specified
  19417.     -- heartbeat_interval then raise a agent suspect error
  19418.     declare hC_qrdr_suspect CURSOR LOCAL FAST_FORWARD for 
  19419.         select sh1.agent_id, sh1.start_time from MSqreader_history sh1 where
  19420.             (sh1.runstatus = 1 or sh1.runstatus = 3 or sh1.runstatus = 4) and
  19421.             dateadd(minute, @heartbeat_interval, sh1.time) < @current_time and
  19422.             sh1.timestamp = (select max(timestamp) from MSqreader_history where
  19423.                 agent_id= sh1.agent_id)
  19424.         for read only
  19425.  
  19426.     open hC_qrdr_suspect
  19427.     fetch hC_qrdr_suspect into @agent_id, @start_time
  19428.     while (@@fetch_status <> -1)
  19429.     begin
  19430.         set @heartbeat_failure = 1
  19431.  
  19432.         -- Get the agent name
  19433.         select @agent_name = name, @job_id = job_id from MSqreader_agents where id = @agent_id
  19434.  
  19435.         -- Log a "No action" message on behalf of the agent
  19436.         exec dbo.sp_MSadd_qreader_history
  19437.             @agent_id = @agent_id,
  19438.             @runstatus = 6,     -- Failure status
  19439.             @comments = @comments,
  19440.             @do_raiserror = 0
  19441.  
  19442.         fetch hC_qrdr_suspect into @agent_id, @start_time
  19443.     end
  19444.     close hC_qrdr_suspect
  19445.     deallocate hC_qrdr_suspect
  19446.  
  19447.     -- Log all is fine message
  19448.     if @heartbeat_failure = 0
  19449.         -- "Detected heartbeat for all running Replication Agents"
  19450.         set @comments = formatmessage(20556)    
  19451.     else
  19452.         -- "Could not detected heartbeat for all running Replication Agents"
  19453.         set @comments = formatmessage(20580)    
  19454.  
  19455.     raiserror (20554, 10, -1, @heartbeat_interval)
  19456. END
  19457. GO
  19458.  
  19459. raiserror(15339,-1,-1,'sp_MSlock_distribution_agent')
  19460. GO
  19461.  
  19462. CREATE PROCEDURE sp_MSlock_distribution_agent (
  19463.     @id int,
  19464.     @mode int = 1 -- 0: shared  1: exclusive
  19465. ) AS
  19466.  
  19467.  
  19468.     SET         NOCOUNT ON
  19469.     DECLARE     @active tinyint
  19470.     declare     @count  int
  19471.     select @active = 2
  19472.     if @mode = 0
  19473.         select @count = count(*) from MSsubscriptions (ROWLOCK REPEATABLEREAD) where agent_id = @id and status = @active
  19474.     else
  19475.         select @count = count(*) from MSsubscriptions (ROWLOCK UPDLOCK) where agent_id = @id and status = @active
  19476. GO
  19477.  
  19478. raiserror(15339,-1,-1,'sp_MSdetect_nonlogged_shutdown')
  19479. GO
  19480. create procedure sp_MSdetect_nonlogged_shutdown
  19481. @subsystem nvarchar(60),
  19482. @agent_id int
  19483. as
  19484.     declare @job_id binary(16)
  19485.     declare @agent_name nvarchar(100)
  19486.     declare @message nvarchar(1024)
  19487.     declare @retcode int
  19488.     declare @runstatus int
  19489.  
  19490.     -- Detect if the agent was shutdown without a logged reason
  19491.     if UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'SNAPSHOT'
  19492.     begin
  19493.         if exists (select runstatus from MSsnapshot_history where 
  19494.             agent_id = @agent_id and
  19495.             runstatus <> 2 and 
  19496. --CAC       runstatus <> 5 and 
  19497.             runstatus <> 6 and
  19498.             timestamp = (select max(timestamp) from MSsnapshot_history where agent_id = @agent_id))
  19499.             begin
  19500.                 select @job_id = job_id, @agent_name = name from MSsnapshot_agents where id = @agent_id
  19501.             end
  19502.     end
  19503.     else if UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'LOGREADER'
  19504.     begin
  19505.         if exists (select runstatus from MSlogreader_history where 
  19506.             agent_id = @agent_id and
  19507.             runstatus <> 2 and 
  19508. --CAC           runstatus <> 5 and 
  19509.             runstatus <> 6 and
  19510.             timestamp = (select max(timestamp) from MSlogreader_history where agent_id = @agent_id))
  19511.             begin
  19512.                 select @job_id = job_id, @agent_name = name from MSlogreader_agents where id = @agent_id
  19513.             end
  19514.     end
  19515.     else if UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'DISTRIBUTION'
  19516.     begin
  19517.         if exists (select runstatus from MSdistribution_history where 
  19518.             agent_id = @agent_id and
  19519.             runstatus <> 2 and 
  19520. --CAC           runstatus <> 5 and 
  19521.             runstatus <> 6 and
  19522.             timestamp = (select max(timestamp) from MSdistribution_history where agent_id = @agent_id))
  19523.             begin
  19524.                 select @job_id = job_id, @agent_name = name from MSdistribution_agents where id = @agent_id
  19525.             end
  19526.     end
  19527.     else if UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'MERGE'
  19528.     begin
  19529.         if exists (select runstatus from MSmerge_history where 
  19530.             agent_id = @agent_id and
  19531.             runstatus <> 2 and 
  19532. --CAC           runstatus <> 5 and 
  19533.             runstatus <> 6 and
  19534.             timestamp = (select max(timestamp) from MSmerge_history where agent_id = @agent_id))
  19535.             begin
  19536.                 select @job_id = job_id, @agent_name = name from MSmerge_agents where id = @agent_id
  19537.             end
  19538.     end
  19539.     else if UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'QUEUEREADER'
  19540.     begin
  19541.         if exists (select runstatus from MSqreader_history where 
  19542.             agent_id = @agent_id and
  19543.             runstatus <> 2 and 
  19544. --CAC       runstatus <> 5 and 
  19545.             runstatus <> 6 and
  19546.             timestamp = (select max(timestamp) from MSqreader_history where agent_id = @agent_id))
  19547.             begin
  19548.                 select @job_id = job_id, @agent_name = name from MSqreader_agents where id = @agent_id
  19549.             end
  19550.     end
  19551.  
  19552.     -- If no job_id assume shutdown was logged properly
  19553.     if @job_id is null
  19554.         return 0
  19555.  
  19556.     -- Get last message from SQL Agent History table
  19557.     create table #JobHistory (
  19558.         instance_id int NOT NULL, 
  19559.         job_id uniqueidentifier NOT NULL,
  19560.         job_name nvarchar(100) NOT NULL,
  19561.         step_id int NOT NULL,
  19562.         step_name nvarchar(100) NOT NULL, 
  19563.         sql_message_id int NOT NULL,
  19564.         sql_severity int NOT NULL,
  19565.         message nvarchar(1024) NOT NULL,
  19566.         run_status int NOT NULL,
  19567.         run_date int NOT NULL,
  19568.         run_time int NOT NULL,
  19569.         run_duration int NOT NULL,
  19570.         operator_emailed sysname NULL,
  19571.         operator_netsent sysname NULL,
  19572.         operator_paged sysname NULL,
  19573.         retries_attempted int NOT NULL,
  19574.         server sysname NOT NULL
  19575.     )
  19576.     if @@error <> 0
  19577.         return 1
  19578.  
  19579.     -- Insert last history for step_id 2 (Agent running)
  19580.     set rowcount 1
  19581.     insert into #JobHistory exec msdb.dbo.sp_help_jobhistory @job_id = @job_id, @step_id = 2, 
  19582.         @mode = 'FULL'          
  19583.  
  19584.     -- Get the last history
  19585.     select @message = message, @runstatus = run_status from #JobHistory
  19586.  
  19587.     -- Reset rowcount
  19588.     set rowcount 0
  19589.  
  19590.     -- Map SQL Agent runstatus to Replication runstatus
  19591.     set @runstatus = 
  19592.     case @runstatus
  19593.         when 0 then 6   -- Fail mapping
  19594.         when 1 then 2   -- Success mapping
  19595.         when 2 then 5   -- Retry mapping
  19596.         when 3 then 2   -- Shutdown mapping
  19597.         when 4 then 3   -- Inprogress mapping
  19598.         when 5 then 0   -- Unknown is mapped to never run
  19599.     end
  19600.  
  19601.     -- If no message, provide a default message
  19602.     -- Also overwrite all inprogress messages to be "See SQL Agent history log".
  19603.     -- This is to prevent "Agent running. See monitor" to be logged into repl monitor.
  19604.     -- In this case (the last job history message is InProgress), we know that
  19605.     -- there have been failures of SQL Server Agent history logging.
  19606.     -- In fact, the only possible "in progress" msg in SQL Agent job step
  19607.     -- history for push jobs is "Agent running. See monitor". It is confusing that those
  19608.     -- messages showed up in repl monitor.
  19609.     if @message is null or @runstatus = 3
  19610.         select @message = formatmessage(20557, @agent_name)
  19611.  
  19612.     if UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'SNAPSHOT'
  19613.         exec @retcode = dbo.sp_MSadd_snapshot_history @agent_id = @agent_id, @runstatus = @runstatus,
  19614.                 @comments = @message
  19615.     else if UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'LOGREADER'
  19616.         exec @retcode = dbo.sp_MSadd_logreader_history @agent_id = @agent_id, @runstatus = @runstatus,
  19617.                 @comments = @message
  19618.     else if UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'DISTRIBUTION'
  19619.         exec @retcode = dbo.sp_MSadd_distribution_history @agent_id = @agent_id, @runstatus = @runstatus,
  19620.                 @comments = @message
  19621.     else if UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'MERGE'
  19622.         exec @retcode = dbo.sp_MSadd_merge_history @agent_id = @agent_id, @runstatus = @runstatus,
  19623.                 @comments = @message
  19624.     else if UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'QUEUEREADER'
  19625.         exec @retcode = dbo.sp_MSadd_qreader_history @agent_id = @agent_id, @runstatus = @runstatus,
  19626.                 @comments = @message
  19627.  
  19628.     if @@error <> 0 or @retcode <> 0
  19629.         return 1
  19630.  
  19631.     drop table #JobHistory
  19632.  
  19633. GO
  19634.  
  19635. raiserror(15339,-1,-1,'sp_MSpublication_access')
  19636. GO
  19637.  
  19638. CREATE PROCEDURE sp_MSpublication_access (
  19639.     @publisher sysname,
  19640.     @publisher_db sysname = NULL,
  19641.     @publication sysname = NULL,
  19642.     @login sysname = NULL,
  19643.     @operation nvarchar(20), -- Can be add/drop/check/help/get_publications/get_logins
  19644.     @has_access bit = 0 output, -- Used only in check
  19645.     @skip bit = 0
  19646.         ) AS
  19647. -- This sp can be called repeatedly.
  19648.     
  19649.     declare @publisher_id smallint
  19650.     declare @retcode int
  19651.     declare @publication_id int
  19652.     declare @isntname bit
  19653.     declare @server_access bit
  19654.     declare @privilege nchar(21)
  19655.  
  19656.     -- Check if publisher is a defined as a distribution publisher in the current database
  19657.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  19658.     if @retcode <> 0
  19659.     begin
  19660.         return(1)
  19661.     end
  19662.  
  19663.     -- Check to see if the login exists and if the login is NT login
  19664.     select @isntname = isntname from master..syslogins where
  19665.         sid = suser_sid(@login) and
  19666.         hasaccess = 1
  19667.  
  19668.     -- Get the publication id 
  19669.     select @publication_id = publication_id from MSpublications where 
  19670.         publisher_id = @publisher_id and
  19671.         publisher_db = @publisher_db and
  19672.         publication = @publication
  19673.  
  19674.     -- Publication does not exist
  19675.     if @publication_id is null and
  19676.         @operation in ('add','drop','check','help')
  19677.     begin
  19678.         raiserror (20026, 16, -1, @publication)
  19679.         return (1)
  19680.     end
  19681.  
  19682.     if @operation = 'add'
  19683.     begin
  19684.         -- Login does not have access
  19685.         if @isntname is null
  19686.         begin
  19687.             if @skip = 0
  19688.             begin
  19689.                 raiserror(21048, 16, -1, @login, @@servername) 
  19690.                 return (1)
  19691.             end
  19692.             else
  19693.                 return (0)
  19694.         end
  19695.  
  19696.         -- Add login to the access list if it does not exist
  19697.         if not exists (select * from MSpublication_access where
  19698.             publication_id = @publication_id and
  19699.             login = @login)
  19700.         begin
  19701.             insert MSpublication_access (publication_id, login)
  19702.                 values (@publication_id,@login)
  19703.             if  @@error <> 0
  19704.                 return(1)
  19705.         end
  19706.     end
  19707.     else if @operation = 'drop'
  19708.     begin
  19709.         if @isntname is null and not exists (select * from MSpublication_access where
  19710.                 publication_id = @publication_id and
  19711.                 login = @login) 
  19712.         begin
  19713.             raiserror(15007,10,-1,@login)
  19714.             return 1
  19715.         end
  19716.         -- Do check existense when dropping since the login might be dropped
  19717.         -- outside replication already.
  19718.         delete MSpublication_access where
  19719.                 publication_id = @publication_id and
  19720.                 login = @login
  19721.         if  @@error <> 0
  19722.             return(1)
  19723.     end
  19724.     else if @operation = 'check'
  19725.     begin
  19726.         -- Cover the case when
  19727.         -- the NT user is not in syslogins
  19728.         if @isntname is null and suser_sid(@login) is not null
  19729.             select @isntname = 1
  19730.  
  19731.         -- If the login is valid NT login, call set user
  19732.         if @isntname = 1
  19733.         begin
  19734.             setuser @login
  19735.             if @@error <> 0
  19736.             begin
  19737.                 raiserror (21142, 16, -1, @@servername, @login)
  19738.                 return(1)
  19739.             end
  19740.         end
  19741.         if exists (select * from MSpublication_access l where
  19742.             publication_id = @publication_id and
  19743.             (l.login = @login or (@isntname = 1 and exists (select * from master..syslogins
  19744.                 where sid = suser_sid(l.login) and isntgroup = 1 and is_member(l.login) = 1))))
  19745.             set @has_access = 1
  19746.         else
  19747.             set @has_access = 0
  19748.         if @isntname = 1
  19749.         begin
  19750.             setuser
  19751.             if @@error <> 0
  19752.                 return(1)
  19753.         end        
  19754.     end
  19755.     else if @operation = 'help'
  19756.     begin
  19757.         select login from MSpublication_access where
  19758.                     publication_id = @publication_id and
  19759.                     login like @login
  19760.     end
  19761.     else if @operation = 'get_publications'
  19762.     begin
  19763.         -- Avoid setuser failure and cover the case of that 
  19764.         -- the NT user is not in syslogins
  19765.         if @isntname is null and suser_sid(@login) is not null
  19766.         begin
  19767.             exec @retcode = master.dbo.xp_logininfo
  19768.                 @login, N'all', @privilege output
  19769.             if @privilege is not null
  19770.                 select @isntname = 1
  19771.         end
  19772.  
  19773.         -- If the login is valid NT login, call set user
  19774.         if @isntname = 1
  19775.         begin
  19776.             setuser @login
  19777.             -- If the login is invalid, don't return any result.
  19778.             if @@error <> 0
  19779.             begin
  19780.                 raiserror (21142, 16, -1, @@servername, @login)
  19781.                 return(0)
  19782.             end
  19783.         end
  19784.         select p.publisher_db, p.publication from MSpublication_access l,
  19785.             MSpublications p where
  19786.             -- Get all the non default publications that have the login in the access list
  19787.             (
  19788.             -- If login match or there is an NT group in the access list and @login is integrated
  19789.             (l.login = @login or ( @isntname = 1 and exists (select * from master..syslogins
  19790.                 where sid = suser_sid(l.login) and isntgroup = 1 and is_member(l.login) = 1))) and
  19791.             l.publication_id = p.publication_id and
  19792.             p.publisher_id = @publisher_id
  19793.             ) 
  19794.         if @isntname = 1
  19795.         begin
  19796.             setuser
  19797.             if @@error <> 0
  19798.                 return(1)
  19799.         end        
  19800.     end
  19801.     else if @operation = 'get_logins'
  19802.     begin
  19803.         select loginname from master..syslogins where
  19804.             hasaccess = 1
  19805.     end
  19806. GO
  19807.  
  19808.  
  19809. raiserror(15339,-1,-1,'sp_MSdrop_6x_publication')
  19810. GO
  19811.  
  19812. -- This stored procedure is called by sp_droptask when 6.x publications are dropped.
  19813. create procedure sp_MSdrop_6x_publication
  19814. @job_id UNIQUEIDENTIFIER
  19815. as
  19816.     declare @publisher sysname
  19817.     declare @publisher_db sysname
  19818.     declare @publication sysname
  19819.     declare @retcode int
  19820.  
  19821.     -- Get publication information
  19822.     select @publisher = srvname, @publisher_db = publisher_db, @publication = publication from 
  19823.         MSsnapshot_agents, master..sysservers where
  19824.         job_id = @job_id and
  19825.         srvid = publisher_id
  19826.  
  19827.     -- Remove the publication and snapshot agent
  19828.     exec @retcode = dbo.sp_MSdrop_publication
  19829.         @publisher = @publisher,
  19830.         @publisher_db = @publisher_db,
  19831.         @publication = @publication 
  19832.     if @@ERROR <> 0 or @retcode <> 0
  19833.         return 1
  19834. GO
  19835.  
  19836. raiserror(15339,-1,-1,'sp_MShelp_distribution_agentid')
  19837. GO
  19838.  
  19839. CREATE PROCEDURE sp_MShelp_distribution_agentid
  19840. @publisher_id smallint,
  19841. @publisher_db sysname,
  19842. @publication sysname = NULL,
  19843. @subscriber_id smallint,
  19844. @subscriber_db sysname,
  19845. @subscription_type int, /* 0 = push 1 = pull 2=anonymous, */
  19846. -- For anonymous only
  19847. @subscriber_name    sysname = NULL,
  19848. @anonymous_subid    uniqueidentifier = NULL,
  19849. @reinitanon         bit = 0
  19850.  
  19851. as
  19852.  
  19853.     set nocount on
  19854.  
  19855.     declare @independent_agent bit
  19856.     declare @xact_seqno_length int
  19857.     declare @agent_id int
  19858.     declare @third_party_flag bit
  19859.     declare @retcode int
  19860.     declare @anonymous int
  19861.     declare @sub_agent_id int
  19862.     declare @allow_subscription_copy bit
  19863.     declare @immediate_sync bit
  19864.  
  19865.     select @anonymous = 2
  19866.     
  19867.     if @publication is null
  19868.         select @independent_agent = 0
  19869.     else
  19870.         select @independent_agent = 1
  19871.  
  19872.     select  top 1
  19873.         @third_party_flag = thirdparty_flag,
  19874.         @allow_subscription_copy = allow_subscription_copy,
  19875.         @immediate_sync = immediate_sync
  19876.         from MSpublications where
  19877.         publisher_id = @publisher_id and
  19878.         publisher_db = @publisher_db and
  19879.         publication = @publication or 
  19880.         (@publication is null and independent_agent = 0)
  19881.  
  19882.     -- Get agent id
  19883.     if @subscription_type = @anonymous
  19884.     begin
  19885.         exec @retcode = dbo.sp_MSadd_anonymous_agent
  19886.             @publisher_id   = @publisher_id,
  19887.             @publisher_db   = @publisher_db,
  19888.             @publication    = @publication,
  19889.             @subscriber_db  = @subscriber_db,
  19890.             @subscriber_name = @subscriber_name,
  19891.             @anonymous_subid =  @anonymous_subid output,
  19892.             @agent_id = @agent_id output,
  19893.             @reinitanon = @reinitanon
  19894.         if @@error <> 0 or @retcode <> 0
  19895.             return (1)
  19896.  
  19897.         -- Refer to sp_MSget_subscription_guid
  19898.         select @sub_agent_id = virtual_agent_id from
  19899.             MSdistribution_agents where
  19900.             id = @agent_id
  19901.     end 
  19902.     else
  19903.     begin
  19904.         select @agent_id = id
  19905.         from MSdistribution_agents where
  19906.              publisher_id = @publisher_id and
  19907.              publisher_db = @publisher_db and
  19908.              (publication = @publication or
  19909.              (@publication is null and publication = N'ALL')) and
  19910.              subscription_type = @subscription_type and
  19911.              subscriber_id = @subscriber_id and
  19912.              subscriber_db = @subscriber_db
  19913.  
  19914.         -- If cannont find the agent entry, ignore @subscriber_db and try again 
  19915.         -- for non SQL subscribers
  19916.         -- Note that this preserved backward compatibility for 7.0 publisher, 7.0 pull distribution agent or 6.5 pub.
  19917.         -- In 7.0, we hard code name 'DSN'.
  19918.         -- In 6.5 pub, the db name is real database name.
  19919.         -- In 8.0, distribution agent sends in unlocalized '(default destination)' as default db name for 
  19920.         -- non SQL subscribers..
  19921.         if @agent_id is null 
  19922.         begin
  19923.             declare @publisher sysname
  19924.             declare @subscriber sysname
  19925.             select @publisher = srvname from master..sysservers where
  19926.                 srvid = @publisher_id
  19927.             select @subscriber = srvname from master..sysservers where
  19928.                 srvid = @subscriber_id
  19929.             if exists (select * from MSsubscriber_info where
  19930.                 publisher = @publisher and
  19931.                 subscriber = @subscriber and
  19932.                 type <> 0)
  19933.             begin
  19934.                 select @agent_id = id
  19935.                 from MSdistribution_agents where
  19936.                      publisher_id = @publisher_id and
  19937.                      publisher_db = @publisher_db and
  19938.                      (publication = @publication or
  19939.                      (@publication is null and publication = N'ALL')) and
  19940.                      subscription_type = @subscription_type and
  19941.                      subscriber_id = @subscriber_id 
  19942.             end
  19943.         end
  19944.  
  19945.         select @sub_agent_id = @agent_id
  19946.     end
  19947.  
  19948.     -- If cannot find the publication and the agent, raise error
  19949.     -- saying invalid publication.
  19950.     -- Note: can not fail if publication not exists but agent exists
  19951.     -- It is an upgrade case. 
  19952.     if @third_party_flag is null and @agent_id is null
  19953.     begin
  19954.         -- The publication(s) does not exist
  19955.         RAISERROR (21073, 16, -1)
  19956.         return(1)
  19957.     end
  19958.  
  19959.     if @agent_id is null
  19960.     begin
  19961.         -- Raise a special error for a common error case: user specified publication
  19962.         -- name for non independent agent publication.
  19963.         -- If the specified publication name is in MSpublications table then
  19964.         -- the publication is configured to use a non-independent distribution
  19965.         -- agent. Raise a different error if this is the case
  19966.         if @publication is not null and 
  19967.             exists (select * from MSpublications 
  19968.                     where publication = @publication and 
  19969.                           publisher_id = @publisher_id and
  19970.                           publisher_db = @publisher_db and
  19971.                           independent_agent = 0)  
  19972.         begin
  19973.             RAISERROR (21133, 16, -1, @publication)
  19974.         end
  19975.         else
  19976.         begin
  19977.             -- Invalid subscription
  19978.             RAISERROR (21056, 16, -1, @publication)
  19979.         end
  19980.         return(1)
  19981.     end
  19982.  
  19983.     -- Reset null properties
  19984.     -- It is an upgrade case. 
  19985.     if @third_party_flag is null 
  19986.         select @third_party_flag = 0
  19987.     if @allow_subscription_copy is null
  19988.         select @allow_subscription_copy = 0
  19989.  
  19990.     /*
  19991.     ** Get the time when the subscription is active and succeed.
  19992.     */
  19993.     /*
  19994.     select Top 1 @last_status=runstatus, @last_sync = time from MSdistribution_history 
  19995.         where agent_id = @agent_id order by timestamp DESC
  19996.     
  19997.     if @last_status = 6 and EXISTS (select * from MSdistribution_history where agent_id = @agent_id and runstatus = @success) 
  19998.                 select Top 1 @last_sync = time from MSdistribution_history where agent_id = @agent_id and runstatus = @success
  19999.                         order by timestamp DESC    
  20000.  
  20001.     if @last_sync is not NULL and @independent_agent = 1 --by pass the retention check for non-independent agnt
  20002.     begin
  20003.         if (@last_sync < dateadd(hour, -@retention, getdate()))
  20004.            and (@retention <> 0)
  20005.                  select @expired = 1 
  20006.     end
  20007.     */
  20008.  
  20009.     /* 
  20010.     ** Avoid returning a NULL value 
  20011.     ** Otherwise, distribution agent may fail
  20012.     */
  20013.     select @xact_seqno_length = 0
  20014.  
  20015.     /* 
  20016.     **  Get the lengh of xact_seqno
  20017.     **   Currently, unique across the publisher
  20018.     */
  20019.     select top 1 @xact_seqno_length = DATALENGTH(subscription_seqno)
  20020.     from MSsubscriptions s where
  20021.         agent_id = @sub_agent_id
  20022.  
  20023.     /* xact_seqno for snapshot trans are longer for native publishers*/
  20024.     if @third_party_flag = 0
  20025.     begin
  20026.         if @xact_seqno_length = 8 or @xact_seqno_length = 10
  20027.             select @xact_seqno_length = @xact_seqno_length + 4
  20028.     end
  20029.  
  20030.     -- Security check. Do it here to let the agent fail at the beginning
  20031.     exec @retcode = dbo.sp_MScheck_pull_access
  20032.         @agent_id = @sub_agent_id,
  20033.         @agent_type = 0 -- distribution agent
  20034.     if @@error <> 0 or @retcode <> 0
  20035.         return (1)
  20036.     
  20037.     -- Get update_mode
  20038.     declare @update_mode int
  20039.     
  20040.     -- Use max because:
  20041.     -- One agent can have mixed read only (0) and synctran (1) subscriptions. 
  20042.     -- The update mode value
  20043.     -- is used in subscriber triggers. It is ok to set update mode to synctran
  20044.     -- in mixed case because the triggers will not be create for read only.
  20045.     -- Queued mode require independent agent.
  20046.     select @update_mode = max(update_mode) from MSsubscriptions where
  20047.         agent_id = @agent_id
  20048.     
  20049.     -- For anonymous agents, update_mode is read only.
  20050.     if @update_mode is null
  20051.         set @update_mode = 0
  20052.  
  20053.     -- Get attach_version guid
  20054.     declare @attach_version binary(16)
  20055.     if @allow_subscription_copy <> 0
  20056.     begin
  20057.         declare @publication_id int
  20058.         declare @virtual_agent_id int
  20059.         declare @virtual smallint
  20060.         set @virtual = -1
  20061.  
  20062.         -- Get publication_id
  20063.         select @publication_id = publication_id
  20064.             from MSpublications where
  20065.             publisher_id = @publisher_id and
  20066.             publisher_db = @publisher_db and
  20067.             publication = @publication 
  20068.  
  20069.         if @publication_id is null
  20070.         begin
  20071.             RAISERROR (21040, 16, -1, @publication)
  20072.             return 1
  20073.         end
  20074.  
  20075.         -- Get version agent_id
  20076.         select top 1 @virtual_agent_id = agent_id from MSsubscriptions where
  20077.             publisher_id = @publisher_id and
  20078.             publisher_db = @publisher_db and
  20079.             publication_id = @publication_id and
  20080.             subscriber_id = @virtual
  20081.  
  20082.         select @attach_version = subscription_guid from MSdistribution_agents
  20083.             where id = @virtual_agent_id
  20084.     end
  20085.     else
  20086.         -- set a irrelevent guid. It should never be used.
  20087.         select @attach_version = newid()
  20088.  
  20089.     -- Get subscription guid
  20090.     -- Use sub_agent_id so that both anonymous and well-known work.
  20091.     -- Refer to sp_MSget_subscription_guid. You need to make change to that sp when changing
  20092.     -- this.
  20093.     declare @subscription_guid binary(16)
  20094.     select @subscription_guid = subscription_guid from MSdistribution_agents where
  20095.         id = @sub_agent_id
  20096.  
  20097.     select 
  20098.         'xact_seqno_length' = @xact_seqno_length,
  20099.         'agent_id' = @agent_id,
  20100.         'agent_name' = name,
  20101.         'anonymous subid' = anonymous_subid,
  20102.         'expired ' = convert(int, 0),
  20103.         'dts_package_name' = dts_package_name,
  20104.         'dts_package_password' = dts_package_password,
  20105.         'dts_package_location' = dts_package_location,
  20106.         'immediate_sync' = @immediate_sync,
  20107.         'allow_subscription_copy' = @allow_subscription_copy,
  20108.         'queue_id' = queue_id,
  20109.         'update_mode' = @update_mode,
  20110.         'attach_version' = @attach_version,
  20111.         'subscription_guid' = @subscription_guid,
  20112.         'queue_server' = queue_server
  20113.         
  20114.         from MSdistribution_agents where id = @agent_id
  20115.  
  20116. GO
  20117.  
  20118. raiserror(15339,-1,-1,'sp_MScheck_tran_retention')
  20119. GO
  20120.  
  20121. CREATE PROCEDURE sp_MScheck_tran_retention
  20122. @xact_seqno varbinary(16),
  20123. @agent_id int
  20124. as
  20125.  
  20126.     set nocount on
  20127.  
  20128.     declare @date datetime
  20129.     declare @retention int
  20130.     declare    @expired int
  20131.     declare @publisher_database_id int
  20132.  
  20133.     select @publisher_database_id = publisher_database_id from MSdistribution_agents
  20134.         where id = @agent_id
  20135.  
  20136.     select @date = entry_time from MSrepl_transactions where
  20137.         xact_seqno = @xact_seqno and
  20138.         publisher_database_id = @publisher_database_id
  20139.  
  20140.     select @retention = max_distretention from msdb..MSdistributiondbs where
  20141.         name = db_name()
  20142.  
  20143.     if (@date is not null and datediff(minute, @date, getdate()) < @retention*60) or
  20144.         -- For 'sync with backup' dist db where
  20145.         -- the dist db might be restored to a previous version so that the subscriber's
  20146.         -- xact_seqno is larger.
  20147.        (@date is null and not exists (select * from MSrepl_transactions where
  20148.         xact_seqno >= @xact_seqno and
  20149.         publisher_database_id = @publisher_database_id))
  20150.         select @expired = 0
  20151.     else
  20152.         select @expired = 1
  20153.     
  20154.     select N'expired' = @expired
  20155.  
  20156. GO
  20157.  
  20158. raiserror(15339,-1,-1,'sp_MSmarkreinit')
  20159. GO
  20160. CREATE PROCEDURE sp_MSmarkreinit
  20161. @publisher sysname,
  20162. @publisher_db sysname,
  20163. @publication sysname,
  20164. @subscriber sysname,       
  20165. @subscriber_db sysname,
  20166. @reset_reinit    int
  20167. AS
  20168.     set nocount on
  20169.  
  20170.     declare @publisher_id smallint
  20171.     declare @subscriber_id smallint
  20172.     declare @publication_id int
  20173.     declare @retcode int
  20174.     declare @reinited int
  20175.     declare @unreinited int
  20176.     declare @status int
  20177.  
  20178.     select @reinited = 4  -- status=4 means this subscription has been reinited
  20179.     select @unreinited = 1 -- status=1 means this subscription not reinited
  20180.  
  20181.     if @reset_reinit = 1
  20182.         select @status = @reinited
  20183.     else
  20184.         select @status = @unreinited
  20185.     
  20186. -- Check if publisher is a defined as a distribution publisher in the current database
  20187.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  20188.     if @retcode <> 0
  20189.     begin
  20190.         return(1)
  20191.     end
  20192.  
  20193.     -- Get the publication information 
  20194.     select @publication_id = publication_id
  20195.         from MSpublications where 
  20196.         publisher_id = @publisher_id and
  20197.         publisher_db = @publisher_db and
  20198.         publication = @publication
  20199.     if @publication_id is NULL
  20200.     begin
  20201.         raiserror (20026, 11, -1, @publication)
  20202.         return (1)
  20203.     end
  20204.  
  20205.     -- Get subscriber info
  20206.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  20207.  
  20208.     update MSmerge_subscriptions set status = @status where
  20209.         publisher_id = @publisher_id and 
  20210.         publisher_db = @publisher_db and 
  20211.         publication_id = @publication_id and
  20212.         subscriber_id = @subscriber_id and
  20213.         subscriber_db = @subscriber_db
  20214.     if @@error<>0 
  20215.         return (1)
  20216. GO        
  20217.  
  20218. raiserror('Creating procedure sp_MSfetchAdjustidentityrange', 0,1)
  20219. GO
  20220.  
  20221. CREATE PROCEDURE sp_MSfetchAdjustidentityrange 
  20222.     @publisher            sysname,
  20223.     @publisher_db        sysname,
  20224.     @tablename            sysname,
  20225.     @adjust_only        bit = 0,
  20226.     @for_publisher        tinyint = 0, --0 for subscriber, 1 for publisher, 2 for republisher
  20227.     @range                bigint = 0 output, -- This parameter is used as input for publisher but output for subscriber
  20228.     @next_seed            bigint = 0 output,
  20229.     @threshold            int = 0 output
  20230. as
  20231.     declare @tmp int
  20232.     if @adjust_only=0
  20233.         select identity_support, next_seed, range, threshold from MSrepl_identity_range
  20234.             where  tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20235.  
  20236.     -- Note: there might be multiple sessions calling this sp at the same time
  20237.     -- Open a transaction so that the update row will be locked so that no one else can
  20238.     -- process this row.
  20239.     begin tran
  20240.     save TRAN sp_MSfetchAdjustidentityrange
  20241.     select @tmp = 1 from MSrepl_identity_range (tablockx holdlock) where 1 = 2
  20242.     if @for_publisher=2 --republishing scenario
  20243.     begin
  20244.         update MSrepl_identity_range set max_identity=@next_seed + @range, next_seed=@next_seed
  20245.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db            
  20246.     end
  20247.     else
  20248.     begin    
  20249.         update MSrepl_identity_range set next_seed = case @for_publisher
  20250.             -- use subscriber's range 
  20251.             when 0 then next_seed + range
  20252.             -- use @range sent in by the publisher
  20253.             else next_seed + @range
  20254.             end
  20255.         where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20256.     end
  20257.  
  20258.     -- for tran pub, max_identity is null
  20259.     if @@ERROR<>0 OR exists (select * from MSrepl_identity_range where ABS(next_seed)>ABS(max_identity))
  20260.     begin
  20261.         raiserror(21195, 16, -1)
  20262.         goto UNDO
  20263.     end
  20264.  
  20265.     select @next_seed = next_seed, @range = range, @threshold = threshold from MSrepl_identity_range
  20266.         where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20267.     
  20268.     commit tran
  20269.     return 0
  20270.  
  20271. UNDO:
  20272.     if @@TRANCOUNT > 0
  20273.     begin
  20274.         ROLLBACK TRAN sp_MSfetchAdjustidentityrange
  20275.         COMMIT TRAN
  20276.     end
  20277.     return(1)
  20278.  
  20279. go            
  20280. exec dbo.sp_MS_marksystemobject sp_MSfetchAdjustidentityrange 
  20281. go
  20282. grant exec on dbo.sp_MSfetchAdjustidentityrange to public
  20283. go
  20284.  
  20285. raiserror(15339,-1,-1,'sp_MSreinit_subscription')
  20286. GO
  20287. CREATE PROCEDURE sp_MSreinit_subscription
  20288. @publisher_name sysname,
  20289. @publisher_db sysname,
  20290. @publication sysname = 'all',
  20291. @subscriber_name    sysname = 'all',
  20292. @subscriber_db sysname = 'all'
  20293. as
  20294.     set nocount on
  20295.     declare @proc nvarchar(2048)
  20296.     declare @retcode int
  20297.  
  20298.     if @publisher_name IS NULL or NOT EXISTS (select * from master..sysservers as ss, MSpublications as msp
  20299.         where lower(ss.srvname) = lower(@publisher_name) and msp.publisher_id = ss.srvid)
  20300.     begin
  20301.         return (1)
  20302.     end
  20303.  
  20304.     if @publisher_db IS NULL
  20305.         select @publisher_db = ''
  20306.  
  20307.     select @proc = @publisher_name + '.' + @publisher_db + '.dbo.sp_reinitsubscription '
  20308.     exec @retcode = @proc @publication, 'all', @subscriber_name, @subscriber_db
  20309.  
  20310.     return (@retcode)
  20311. go
  20312.  
  20313.    -- View for delivered and undelivered commands.   RHS  6-4-98
  20314.    -- Since the view is likely to change, just recreate it each time.
  20315.    IF EXISTS (SELECT * FROM sysobjects where name='MSdistribution_status' and type='V')
  20316.     DROP VIEW dbo.MSdistribution_status
  20317.  
  20318.     /****************************************************************************/
  20319.     raiserror('Creating view MSdistribution_status', 0,1)
  20320.         /****************************************************************************/    
  20321. go
  20322.  
  20323. CREATE VIEW MSdistribution_status (article_id,agent_id,UndelivCmdsInDistDB,DelivCmdsInDistDB)
  20324. as
  20325. -- Note that this view does not account for (i.e. exclude from counts) commands that do not need to be delivered 
  20326. -- because of loopback or syncronous updating subscribers, nor subscriptions never activated.
  20327. -- It also may not be exact due to use of NOLOCK - so that it does not cause blocking or deadlock issues.
  20328. SELECT t.article_id,s.agent_id,
  20329. 'UndelivCmdsInDistDB'=SUM(CASE WHEN xact_seqno > h.maxseq THEN 1 ELSE 0 END),
  20330. 'DelivCmdsInDistDB'=SUM(CASE WHEN xact_seqno <=  h.maxseq THEN 1 ELSE 0 END)
  20331. FROM    (SELECT    article_id,publisher_database_id, xact_seqno
  20332.     FROM MSrepl_commands (NOLOCK) ) as t
  20333. JOIN (SELECT agent_id,article_id,publisher_database_id FROM MSsubscriptions (NOLOCK) ) AS s 
  20334. ON (t.article_id = s.article_id AND t.publisher_database_id=s.publisher_database_id )
  20335. JOIN (SELECT agent_id,'maxseq'= isnull(max(xact_seqno),0x0) FROM MSdistribution_history (NOLOCK) GROUP BY agent_id) as h
  20336. ON (h.agent_id=s.agent_id)
  20337. GROUP BY t.article_id,s.agent_id
  20338. go
  20339.     
  20340. EXEC dbo.sp_MS_marksystemobject 'MSdistribution_status'
  20341. -- As this view can add considerable overhead when queried, it intentionally is not granted public access by default.
  20342. -- A site may so grant it if it wants to of course>
  20343. GRANT SELECT ON MSdistribution_status to dbo
  20344. go
  20345.  
  20346.  
  20347. raiserror(15339,-1,-1,'sp_browsereplcmds')
  20348. GO
  20349.  
  20350. create procedure sp_browsereplcmds 
  20351. @xact_seqno_start nchar(22) = NULL, 
  20352. @xact_seqno_end nchar(22) = NULL,
  20353. @originator_id int = NULL,
  20354. @publisher_database_id int = NULL,
  20355. @article_id int = NULL,
  20356. @command_id int = NULL,
  20357. @results_table sysname = NULL
  20358. as
  20359. declare @query nvarchar( 4000 )
  20360. declare @dbname sysname
  20361.  
  20362. if( @command_id is not null )
  20363. begin
  20364.     if( @xact_seqno_start is null or @publisher_database_id is null )
  20365.     begin
  20366.         raiserror( 21110, 16, -1 )
  20367.         return 1
  20368.     end
  20369.     else if @xact_seqno_start != @xact_seqno_end 
  20370.     begin
  20371.         raiserror( 21109, 16, -1 )
  20372.         return 1
  20373.     end
  20374. end
  20375.  
  20376. if @results_table is not null
  20377. begin
  20378.     select @query = N'create table ' + @results_table + N'('
  20379.     select @query = @query + N'xact_seqno varbinary(16) null,'
  20380.     select @query = @query + N'originator_id int null,'
  20381.     select @query = @query + N'publisher_database_id int null,'
  20382.     select @query = @query + N'article_id int null,'
  20383.     select @query = @query + N'type int null,'
  20384.     select @query = @query + N'command nvarchar( 1024 ) null )'
  20385.  
  20386.     exec ( @query )
  20387.     if @@error <> 0
  20388.     begin
  20389.         return 1
  20390.     end
  20391. end
  20392.  
  20393. if @xact_seqno_start is null
  20394. begin
  20395.     select @xact_seqno_start = N'0x00000000000000000000'
  20396. end
  20397. if @xact_seqno_end is null
  20398. begin
  20399.     select @xact_seqno_end = N'0xFFFFFFFFFFFFFFFFFFFF'
  20400. end
  20401.  
  20402. select @query = N'select xact_seqno, convert( int, originator_id ), convert( int, publisher_database_id ), convert(int, article_id), convert( int, type ), convert( int, partial_command ), command from MSrepl_commands '
  20403.  
  20404. if @command_id is not null
  20405. begin
  20406.     select @query = @query + N'where xact_seqno = ' + @xact_seqno_start  
  20407. end
  20408. else
  20409. begin
  20410.     select @query = @query + N'where xact_seqno >= ' + @xact_seqno_start + N' and xact_seqno <= ' + @xact_seqno_end 
  20411. end
  20412.  
  20413. if @originator_id is not null
  20414. begin
  20415.     select @query = @query + N' and originator_id = ' + convert( nvarchar, @originator_id )
  20416. end
  20417.  
  20418. if @publisher_database_id is not null
  20419. begin
  20420.     select @query = @query + N' and publisher_database_id = ' + convert( nvarchar, @publisher_database_id )
  20421. end
  20422.  
  20423. if @article_id is not null
  20424. begin
  20425.     select @query = @query + N' and article_id = ' + convert( nvarchar, @article_id )
  20426. end
  20427.  
  20428. if @command_id is not null
  20429. begin
  20430.     -- No need to use article_id and originator_id
  20431.     select @query = @query + N' and command_id >= ' + convert( nvarchar, @command_id )
  20432.     select @query = @query + N' and command_id <= ( select min( command_id ) from MSrepl_commands c '
  20433.     select @query = @query + N' where c.xact_seqno = ' + @xact_seqno_start  
  20434.     select @query = @query + N' and c.publisher_database_id = ' + convert( nvarchar, @publisher_database_id )
  20435.     select @query = @query + N' and c.command_id >= ' + convert( nvarchar, @command_id )
  20436.     select @query = @query + N' and c.partial_command = 0 )'  
  20437. end
  20438.  
  20439. select @query = @query + N' order by originator_id, publisher_database_id, xact_seqno, article_id, command_id asc'
  20440.  
  20441. select @dbname = db_name()
  20442.  
  20443. if @results_table is not null
  20444. begin
  20445.     declare @q2 nvarchar(4000)
  20446.     select @query = replace( @query, '''', '''''' )
  20447.     select @q2 = N'insert into ' + @results_table + N' exec master..xp_printstatements N'''+ @query + N''',N''' + @dbname  +''''
  20448.     exec (@q2)
  20449. end
  20450. else
  20451. begin
  20452.     exec master..xp_printstatements @query, @dbname
  20453. end
  20454. go
  20455.  
  20456.  
  20457.  
  20458. raiserror(15339,-1,-1,'sp_dumpparamcmd')
  20459. GO
  20460.  
  20461. create procedure sp_dumpparamcmd
  20462. @originator_id int,
  20463. @publisher_database_id int,
  20464. @article_id int,
  20465. @xact_seqno nchar(22)
  20466. as
  20467. declare @query nvarchar(2048)
  20468. declare @dbname sysname
  20469.  
  20470. select @query = N'select convert(int, partial_command) , command from MSrepl_commands '
  20471. select @query = @query + 'where type = 30 and xact_seqno = ' + @xact_seqno
  20472. select @query = @query + N' and originator_id = ' + convert( nvarchar, @originator_id )
  20473. select @query = @query + N' and publisher_database_id = ' + convert( nvarchar, @publisher_database_id )
  20474. select @query = @query + N' and article_id = ' + convert( nvarchar, @article_id )
  20475. select @query = @query + N' order by command_id asc'
  20476. select @dbname = db_name()
  20477.  
  20478. exec master..xp_displayparamstmt @query, @dbname, 1
  20479. go
  20480.  
  20481. raiserror(15339,-1,-1,'sp_MSbrowsesnapshotfolder')
  20482. GO
  20483.  
  20484. create procedure sp_MSbrowsesnapshotfolder (
  20485.     @publisher     sysname,
  20486.     @publisher_db  sysname,
  20487.     @article_id    int,
  20488.     @subscriber    sysname = NULL,
  20489.     @subscriber_db sysname = NULL
  20490.     )
  20491. AS
  20492.     SET NOCOUNT ON
  20493.  
  20494.  
  20495.     DECLARE @alt_directory_type     INT
  20496.     DECLARE @directory_type         INT
  20497.     DECLARE @publisher_id           INT
  20498.     DECLARE @publisher_database_id  INT
  20499.     DECLARE @subscriber_id          INT
  20500.     DECLARE @snapshot_bit           INT
  20501.     DECLARE @snapshot_mask          INT
  20502.     DECLARE @xact_seqno             VARBINARY(16)
  20503.     DECLARE @sync_init              INT
  20504.     DECLARE @sync_done              INT
  20505.  
  20506.     SELECT @alt_directory_type = 25
  20507.     SELECT @directory_type = 7
  20508.     SELECT @subscriber_id = NULL
  20509.     SELECT @snapshot_bit = 0x80000000
  20510.     SELECT @snapshot_mask = ~@snapshot_bit
  20511.     SELECT @xact_seqno = NULL
  20512.     SELECT @sync_init = 37
  20513.     SELECT @sync_done = 38
  20514.  
  20515.     SELECT @publisher_id = srvid 
  20516.       FROM master.dbo.sysservers 
  20517.      WHERE UPPER(@publisher) = UPPER(srvname)
  20518.  
  20519.     SELECT @publisher_database_id = publisher_database_id 
  20520.       FROM MSsubscriptions
  20521.      WHERE publisher_id = @publisher_id
  20522.        AND publisher_db = @publisher_db
  20523.        AND article_id = @article_id  
  20524.  
  20525.  
  20526.     -- @subscriber is null implies @subscriber_db is null also because 
  20527.     -- this sp can only be called by sp_browsesnapshotfolder
  20528.     IF @subscriber IS NULL
  20529.     BEGIN
  20530.         SELECT @xact_seqno = MAX(xact_seqno) 
  20531.           FROM MSrepl_commands
  20532.          WHERE publisher_database_id = @publisher_database_id
  20533.            AND article_id = @article_id
  20534.            AND (type & @snapshot_bit) <> 0            
  20535.            AND (type & @snapshot_mask) <> @sync_init
  20536.            AND (type & @snapshot_mask) <> @sync_done
  20537.     END
  20538.     ELSE 
  20539.     BEGIN
  20540.         -- Both @subscriber and @subscriber_db are non-null
  20541.         SELECT @subscriber_id = srvid 
  20542.           FROM master.dbo.sysservers
  20543.          WHERE UPPER(@subscriber) = UPPER(srvname)
  20544.         
  20545.         IF @subscriber_id IS NULL
  20546.         BEGIN
  20547.             RAISERROR(21150, 16, -1)  
  20548.             RETURN 1
  20549.         END
  20550.         
  20551.         SELECT @xact_seqno = subscription_seqno 
  20552.           FROM MSsubscriptions
  20553.          WHERE publisher_database_id = @publisher_database_id
  20554.            AND publisher_id = @publisher_id 
  20555.            AND article_id = @article_id
  20556.            AND subscriber_id = @subscriber_id
  20557.            AND subscriber_db = @subscriber_db
  20558.  
  20559.         IF @xact_seqno IS NULL
  20560.         BEGIN
  20561.             RAISERROR(14055, 16, -1)
  20562.             RETURN 1
  20563.         END                  
  20564.     END
  20565.  
  20566.     SELECT 'snapshot_folder' = CONVERT(NVARCHAR(255), command) 
  20567.       FROM MSrepl_commands 
  20568.      WHERE publisher_database_id = @publisher_database_id
  20569.        AND (type & @snapshot_bit) <> 0
  20570.        AND xact_seqno = @xact_seqno
  20571.        AND (((type & ~@snapshot_bit) = @alt_directory_type) OR
  20572.             ((type & ~@snapshot_bit) = @directory_type))
  20573.   ORDER BY command_id ASC
  20574.     IF @@ERROR <> 0
  20575.     BEGIN
  20576.         RETURN 1
  20577.     END
  20578.     ELSE
  20579.     BEGIN
  20580.         RETURN 0
  20581.     END
  20582. GO
  20583.  
  20584. raiserror(15339,-1,-1,'sp_MSchange_subscription_dts_info')
  20585. GO
  20586.  
  20587. CREATE PROCEDURE sp_MSdist_adjust_identity
  20588.     @agent_id    int,
  20589.     @tablename    sysname
  20590. as    
  20591.     declare @publisher sysname
  20592.     declare @publisher_db sysname
  20593.     declare @publisher_id smallint
  20594.     declare @publication sysname
  20595.     declare @next_seed bigint
  20596.     declare @range bigint
  20597.     declare @threshold int
  20598.     declare @retcode int
  20599.  
  20600.     -- Security check.
  20601.     exec @retcode = dbo.sp_MScheck_pull_access
  20602.         @agent_id = @agent_id,
  20603.         @agent_type = 0 -- distribution agent
  20604.     if @@error <> 0 or @retcode <> 0
  20605.         return (1)
  20606.  
  20607.     select @publication = publication, @publisher_id = publisher_id,
  20608.         @publisher_db = publisher_db from MSdistribution_agents where
  20609.         id = @agent_id
  20610.  
  20611.     select @publisher = srvname from master..sysservers where 
  20612.         srvid = @publisher_id
  20613.     -- Get the publication id.
  20614.     -- Note: auto identity range is only supported for queued tran pub
  20615.     -- which implies independent agent.
  20616.     declare @publication_id int
  20617.     select @publication_id = publication_id from MSpublications    where
  20618.         publication =  @publication and
  20619.         publisher_id = @publisher_id and
  20620.         publisher_db = @publisher_db
  20621.  
  20622.     -- Get the source object name
  20623.     declare @src_object sysname
  20624.     select @src_object = source_object from MSarticles where
  20625.         publication_id = @publication_id and
  20626.         destination_object = @tablename
  20627.  
  20628.     if @src_object is not null
  20629.     begin
  20630.         exec @retcode = dbo.sp_MSfetchAdjustidentityrange
  20631.             @publisher = @publisher,
  20632.             @publisher_db = @publisher_db,
  20633.             @tablename = @src_object,
  20634.             @adjust_only = 1,
  20635.             @for_publisher = 0,
  20636.             @next_seed = @next_seed output,
  20637.             @range = @range output,
  20638.             @threshold = @threshold output
  20639.         if @@error <> 0 or @retcode <> 0
  20640.             return 1
  20641.     end
  20642.  
  20643.     -- Return nothing if the table is not found in the table collection served by
  20644.     -- the distribution agent.
  20645.     select 'next_seed' = @next_seed, 'range' = @range, 'threshold' = @threshold
  20646.         where @next_seed is not null 
  20647. go            
  20648.  
  20649. raiserror(15339,-1,-1,'sp_MSdist_adjust_identity')
  20650. GO
  20651.  
  20652. CREATE PROCEDURE sp_MSchange_subscription_dts_info (
  20653.     @job_id varbinary(16),
  20654.     @dts_package_name sysname,
  20655.     @dts_package_password nvarchar(524),
  20656.     @dts_package_location int,
  20657.     @change_password bit
  20658.  
  20659.     ) AS
  20660.  
  20661.     /*
  20662.     ** Declarations.
  20663.     */
  20664.     declare @subscriber sysname
  20665.     declare @publisher sysname
  20666.     declare @subscriber_id smallint
  20667.     declare @publisher_id smallint
  20668.  
  20669.     /*
  20670.     ** Initializations.
  20671.     */
  20672.     SET NOCOUNT ON
  20673.     
  20674.     select @subscriber_id = subscriber_id, @publisher_id = publisher_id 
  20675.         from MSdistribution_agents where 
  20676.         job_id = @job_id
  20677.     
  20678.     select @subscriber = srvname from master..sysservers where srvid = @subscriber_id
  20679.     select @publisher = srvname from master..sysservers where srvid = @publisher_id
  20680.  
  20681.     declare @oledb_subscriber tinyint
  20682.     select @oledb_subscriber = 3
  20683.     
  20684.     -- Only SQL Server and OLEDB subscriber support dts
  20685.     if not exists (select * from MSsubscriber_info where 
  20686.         UPPER(publisher) = UPPER(@publisher) and 
  20687.         UPPER(subscriber) = UPPER(@subscriber) and
  20688.         (type = 0 or type = @oledb_subscriber))
  20689.     begin
  20690.         raiserror(21170, 16, -1)
  20691.         return 1
  20692.     end
  20693.     
  20694.     
  20695.     update MSdistribution_agents set
  20696.         dts_package_name = case 
  20697.             when @dts_package_name is null then dts_package_name
  20698.             when @dts_package_name = N'' then null
  20699.             else @dts_package_name
  20700.             end, 
  20701.         dts_package_password = case @change_password
  20702.             when 0 then dts_package_password
  20703.             else @dts_package_password
  20704.             end, 
  20705.         dts_package_location = case
  20706.             when @dts_package_location is null then dts_package_location
  20707.             else @dts_package_location
  20708.             end
  20709.         where
  20710.             job_id = @job_id
  20711.  
  20712.     RETURN (0)
  20713. go
  20714.  
  20715. raiserror(15339,-1,-1,'sp_MSrefresh_anonymous')
  20716. GO
  20717. CREATE PROCEDURE sp_MSrefresh_anonymous (
  20718. @publication            sysname,
  20719. @publisher                sysname,
  20720. @publisher_db            sysname
  20721. )AS
  20722.  
  20723. declare @retcode         int
  20724. declare @publisher_id    int
  20725. declare @success        int
  20726. declare @agent_id        int
  20727.  
  20728. SELECT @publisher_id = NULL 
  20729. SELECT @publisher_id = srvid FROM master..sysservers WHERE UPPER(@publisher) = UPPER(srvname)  
  20730. IF @publisher_id IS NULL
  20731.     BEGIN
  20732.         RAISERROR(21169, 16, -1, @publisher, @@SERVERNAME, @publisher)    
  20733.         return (1)
  20734.     END
  20735. select @success = 2 --agent history status
  20736.  
  20737. select @agent_id = id from MSmerge_agents where 
  20738.     anonymous_subid is not NULL and --touch anonymous only
  20739.     publication like @publication and 
  20740.     publisher_id=@publisher_id and 
  20741.     publisher_db=@publisher_db
  20742.  
  20743. set rowcount 1
  20744. update MSmerge_history set time=getdate() where agent_id=@agent_id and runstatus=@success
  20745. if @@ERROR<>0
  20746.     return (1)
  20747. GO
  20748.  
  20749. raiserror(15339,-1,-1,'sp_MScheck_pub_identity')
  20750. GO
  20751. CREATE PROCEDURE sp_MScheck_pub_identity (
  20752. @publisher            sysname,
  20753. @publisher_db        sysname,
  20754. @tablename            sysname, 
  20755. @current_max        bigint  = NULL OUTPUT,
  20756. @pub_range            bigint  = NULL OUTPUT,
  20757. @threshold            int  = NULL OUTPUT,
  20758. @range                bigint  = NULL OUTPUT,
  20759. @next_seed            bigint  = NULL OUTPUT,
  20760. @max_identity        bigint = NULL OUTPUT
  20761. )AS
  20762.  
  20763.     declare @retcode        int
  20764.  
  20765.     if @current_max is not NULL
  20766.     begin
  20767.         select @current_max=current_max from MSrepl_identity_range 
  20768.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20769.         if @@ERROR<>0    
  20770.             return (1)
  20771.     end
  20772.  
  20773.     if @max_identity is not NULL
  20774.     begin
  20775.         select @max_identity=max_identity from MSrepl_identity_range 
  20776.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20777.         if @@ERROR<>0    
  20778.             return (1)
  20779.     end
  20780.  
  20781.     if @pub_range is not NULL
  20782.     begin
  20783.         select @pub_range=pub_range from MSrepl_identity_range 
  20784.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20785.         if @@ERROR<>0    
  20786.             return (1)
  20787.     end
  20788.  
  20789.     if @threshold is not NULL
  20790.     begin
  20791.         select @threshold=threshold from MSrepl_identity_range 
  20792.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20793.         if @@ERROR<>0    
  20794.             return (1)
  20795.     end
  20796.     if @next_seed is not NULL
  20797.     begin
  20798.         select @next_seed=next_seed from MSrepl_identity_range 
  20799.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20800.         if @@ERROR<>0    
  20801.             return (1)
  20802.     end
  20803.     if @range is not NULL
  20804.     begin
  20805.         select @range=range from MSrepl_identity_range 
  20806.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20807.         if @@ERROR<>0    
  20808.             return (1)
  20809.     end
  20810.  
  20811. return (0)
  20812. GO
  20813.  
  20814. raiserror(15339,-1,-1,'sp_MSadjust_pub_identity')
  20815. GO
  20816.  
  20817. CREATE PROCEDURE sp_MSadjust_pub_identity (
  20818. @publisher            sysname,
  20819. @publisher_db        sysname,
  20820. @tablename            sysname,
  20821. @current_max        int  = NULL,
  20822. @threshold            int  = NULL,
  20823. @range                int = NULL,
  20824. @next_seed            int  = NULL
  20825. )AS
  20826.  
  20827.     declare @retcode        int
  20828.     if @current_max is NOT NULL
  20829.     begin
  20830.         update MSrepl_identity_range set current_max=@current_max 
  20831.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20832.         if @@ERROR<>0    
  20833.             return (1)
  20834.         if exists (select * from MSrepl_identity_range where max_identity is not NULL 
  20835.             and ABS(current_max) > ABS(max_identity))
  20836.         begin
  20837.             raiserror(21195, 16, -1)
  20838.             return (1)
  20839.         end
  20840.     end
  20841.     if @threshold is NOT NULL
  20842.     begin
  20843.     update MSrepl_identity_range set threshold=@threshold 
  20844.         where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20845.     if @@ERROR<>0    
  20846.         return (1)
  20847.     end
  20848.     if @next_seed is NOT NULL
  20849.     begin
  20850.     update MSrepl_identity_range set next_seed=@next_seed 
  20851.         where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20852.     if @@ERROR<>0
  20853.         return (1)
  20854.     end
  20855.     if @range is NOT NULL
  20856.     begin
  20857.     update MSrepl_identity_range set range=@range 
  20858.         where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db    
  20859.     if @@ERROR<>0
  20860.         return (1)
  20861.     end
  20862. return (0)
  20863. GO
  20864.  
  20865. raiserror(15339,-1,-1,'sp_MSinsert_identity')
  20866. GO
  20867.  
  20868. CREATE PROCEDURE sp_MSinsert_identity (
  20869.     @publisher             sysname,
  20870.     @publisher_db         sysname,
  20871.     @tablename             sysname,
  20872.     @identity_support    int,
  20873.     @pub_identity_range bigint,
  20874.     @identity_range     bigint,
  20875.     @threshold             int,
  20876.     @next_seed            bigint,
  20877.     @max_identity        bigint
  20878.     ) AS
  20879.     
  20880.     declare @pub_seed         bigint    
  20881.     declare @current_max     bigint
  20882.     if not exists (select * from MSrepl_identity_range 
  20883.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db)
  20884.     begin
  20885.         select @pub_seed = @pub_identity_range + @next_seed
  20886.         select @current_max = @pub_seed - 1
  20887.         insert MSrepl_identity_range(publisher, publisher_db, tablename, identity_support, next_seed, pub_range, range, max_identity, threshold, current_max    )
  20888.                 values (@publisher, @publisher_db, @tablename, @identity_support, @pub_seed,  @pub_identity_range, @identity_range, @max_identity, @threshold, @current_max)
  20889.         if @@ERROR<>0
  20890.             return 1
  20891.     end
  20892.     else if 1 > 1 --disable this segment for now.
  20893.         begin --adjust republisher's resource table
  20894.             select @pub_seed = @pub_identity_range - 1
  20895.             /* update range, threshold at republisher as needed. Max and next_seed has been set already. */
  20896.             update MSrepl_identity_range set    range = @identity_range,
  20897.                                                 pub_range = @pub_identity_range,
  20898.                                                 threshold=@threshold, 
  20899.                                                 next_seed=next_seed + @pub_identity_range,
  20900.                                                 current_max=next_seed + @pub_seed --new next_seed not yet picked up
  20901.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20902.             if @@ERROR<>0
  20903.                 return (1)
  20904.         end
  20905. GO
  20906.  
  20907. raiserror(15339,-1,-1,'sp_MSget_subscription_dts_info')
  20908. GO
  20909.  
  20910. CREATE PROCEDURE sp_MSget_subscription_dts_info (
  20911.     @job_id varbinary(16)
  20912.  
  20913.     ) AS
  20914.  
  20915.     /*
  20916.     ** Declarations.
  20917.     */
  20918.  
  20919.     /*
  20920.     ** Initializations.
  20921.     */
  20922.     SET NOCOUNT ON
  20923.  
  20924.     select dts_package_name, dts_package_location 
  20925.         from MSdistribution_agents where
  20926.         job_id = @job_id
  20927.  
  20928.     RETURN (0)
  20929. go
  20930.  
  20931. raiserror(15339, -1, -1, 'sp_MSenumdistributionagentproperties')
  20932. GO
  20933.  
  20934. CREATE PROCEDURE sp_MSenumdistributionagentproperties (
  20935.     @publisher        sysname,
  20936.     @publisher_db     sysname,
  20937.     @publication      sysname
  20938.     ) AS
  20939.     DECLARE @independent_agent bit 
  20940.     DECLARE @publisher_id int  -- Server id of the Publisher with respect to the Distributor
  20941.    
  20942.     SELECT @publisher_id = NULL 
  20943.     SELECT @publisher_id = srvid 
  20944.       FROM master..sysservers
  20945.      WHERE UPPER(@publisher) = UPPER(srvname)  
  20946.     
  20947.     IF @publisher_id IS NULL
  20948.     BEGIN
  20949.         RAISERROR(21169, 16, -1, @publisher, @@SERVERNAME, @publisher)    
  20950.     END
  20951.  
  20952.     IF @publication <> '%' -- A publication name is specified 
  20953.     BEGIN
  20954.         -- Determine whether the given publication shares an 
  20955.         -- agent with other publicaitons in the same database
  20956.         -- or not
  20957.         SELECT @independent_agent = 0
  20958.         SELECT @independent_agent = independent_agent 
  20959.           FROM MSpublications
  20960.          WHERE publisher_id = @publisher_id
  20961.            AND publisher_db = @publisher_db
  20962.            AND publication = @publication  
  20963.         
  20964.         IF @independent_agent IS NULL
  20965.         BEGIN
  20966.             RAISERROR(20026, 16, -1)
  20967.         END
  20968.  
  20969.         IF @independent_agent = 0 
  20970.         BEGIN
  20971.             -- If the publication shares an agent with 
  20972.             -- other publications, change the publication
  20973.             -- name to 'ALL' before querying the MSdistribution_agents
  20974.             -- table
  20975.             SELECT @publication = N'ALL'                
  20976.         END
  20977.  
  20978.         SELECT job_id, offload_enabled, offload_server, 
  20979.                dts_package_name, dts_package_location,
  20980.                -- status of this agent, only useful in detecting
  20981.                -- whether or not the agent has be deactivated by cleanup
  20982.                -- If so, all the rows in MSsubscriptions will be 0
  20983.                (select top 1 s.status from MSsubscriptions s where
  20984.                     s.agent_id = a.id)
  20985.           FROM MSdistribution_agents a
  20986.          WHERE a.publisher_id = @publisher_id 
  20987.            AND a.publisher_db = @publisher_db
  20988.            AND a.publication = @publication
  20989.     END
  20990.     ELSE
  20991.     BEGIN
  20992.         SELECT job_id, offload_enabled, offload_server, 
  20993.                dts_package_name, dts_package_location,
  20994.                -- status of this agent, only useful in detecting
  20995.                -- whether or not the agent has be deactivated by cleanup
  20996.                -- If so, all the rows in MSsubscriptions will be 0
  20997.                (select top 1 s.status from MSsubscriptions s where
  20998.                     s.agent_id = a.id)
  20999.           FROM MSdistribution_agents a
  21000.          WHERE a.publisher_id = @publisher_id 
  21001.            AND a.publisher_db = @publisher_db
  21002.     END
  21003. GO
  21004.     
  21005. raiserror(15339, -1, -1, 'sp_MSenum_merge_agent_properties')
  21006. GO
  21007. CREATE PROCEDURE sp_MSenum_merge_agent_properties (
  21008.     @publisher        sysname,
  21009.     @publisher_db     sysname,
  21010.     @publication      sysname
  21011.     ) AS
  21012.     
  21013.     DECLARE @publisher_id int  -- Server id of the Publisher with respect to the Distributor
  21014.  
  21015.     SELECT @publisher_id = NULL 
  21016.     SELECT @publisher_id = srvid 
  21017.       FROM master..sysservers
  21018.      WHERE UPPER(@publisher) = UPPER(srvname)  
  21019.  
  21020.     IF @publisher_id IS  NULL
  21021.     BEGIN
  21022.         RAISERROR(21169, 16, -1, @publisher, @@SERVERNAME, @publisher)    
  21023.     END
  21024.  
  21025.     SELECT job_id, offload_enabled, offload_server 
  21026.       FROM MSmerge_agents
  21027.      WHERE publisher_id = @publisher_id 
  21028.        AND publisher_db = @publisher_db
  21029.        AND (@publication = N'%' OR publication = @publication)
  21030. GO
  21031.  
  21032. raiserror(15339, -1, -1, 'sp_dropanonymoussubscription')
  21033. GO
  21034. CREATE PROCEDURE sp_dropanonymoussubscription
  21035. @agent_id int,
  21036. @type int -- 1 tran sub, 2 merge sub
  21037. as
  21038.     declare @retcode int
  21039.     if @type not in (1,2)
  21040.     begin
  21041.         raiserror(20587, 16, -1, '@type', 'sp_dropanonymoussubscription')
  21042.         return (1)
  21043.     end
  21044.     -- If tran
  21045.     if @type = 1
  21046.     begin
  21047.         if not exists (select * from MSdistribution_agents where
  21048.             id = @agent_id and
  21049.             subscriber_name is not null)
  21050.         begin
  21051.             RAISERROR (14055, 11, -1)
  21052.             return(1)
  21053.         end
  21054.         exec @retcode = dbo.sp_MSdrop_distribution_agentid @agent_id
  21055.         if @retcode <> 0 or @@error <> 0
  21056.             return 1
  21057.     end
  21058.     else
  21059.     begin
  21060.         if not exists (select * from MSmerge_agents where
  21061.             id = @agent_id and
  21062.             subscriber_name is not null)
  21063.         begin
  21064.             RAISERROR (14055, 11, -1)
  21065.             return(1)
  21066.         end
  21067.         exec @retcode = dbo.sp_MSdrop_merge_agentid @agent_id
  21068.         if @retcode <> 0 or @@error <> 0
  21069.             return 1
  21070.     end
  21071. go
  21072.  
  21073. raiserror(15339, -1, -1, 'sp_MSdrop_anonymous_entry')
  21074. GO
  21075. CREATE PROCEDURE sp_MSdrop_anonymous_entry
  21076. @subid uniqueidentifier,
  21077. @login sysname,
  21078. @type int -- 1 tran sub, 2 merge sub
  21079. as
  21080.     declare @sid varbinary(85)
  21081.     declare @agent_id int, @retcode int
  21082.     set nocount on 
  21083.     if @type not in (1,2)
  21084.     begin
  21085.         raiserror(20587, 16, -1, '@type', 'sp_MSdrop_anonymous_entry')
  21086.         return (1)
  21087.     end
  21088.     -- If tran
  21089.     if @type = 1
  21090.     begin
  21091.         select @sid = sid from MSdistribution_agents where
  21092.             anonymous_subid = @subid
  21093.     end
  21094.     else
  21095.     begin
  21096.         select @sid = sid from MSmerge_agents where
  21097.             anonymous_subid = @subid
  21098.     end
  21099.     if @sid is null
  21100.     begin
  21101.         RAISERROR (14055, 11, -1)
  21102.         return(1)
  21103.     end
  21104.     -- null login means no security check needed
  21105.     if @login is not null and suser_sid(@login) <> @sid
  21106.     begin
  21107.         set @login = suser_sname(@sid)
  21108.         RAISERROR (20596, 11, -1, @login)
  21109.         RETURN (1)
  21110.     end
  21111.  
  21112.     if @type = 1
  21113.     begin
  21114.         select @agent_id = id from MSdistribution_agents where anonymous_subid = @subid
  21115.         if @agent_id is not null
  21116.         begin
  21117.             exec @retcode = dbo.sp_MSdrop_distribution_agentid @agent_id
  21118.             if @retcode <> 0 or @@error <> 0
  21119.                 return 1
  21120.         end
  21121.     end
  21122.     else
  21123.     begin
  21124.         select @agent_id = id from MSmerge_agents where anonymous_subid = @subid
  21125.         if @agent_id is not null
  21126.         begin
  21127.             exec @retcode = dbo.sp_MSdrop_merge_agentid @agent_id
  21128.             if @retcode <> 0 or @@error <> 0
  21129.                 return 1
  21130.         end
  21131.     end
  21132. go
  21133.  
  21134. raiserror(15339, -1, -1, 'sp_MSadddynamicsnapshotjobatdistributor')
  21135. go
  21136. --
  21137. -- Name: sp_MSadddynamicsnapshotjobatdistributor
  21138. --
  21139. -- Description: This function is called by sp_MSaddmergedynamicsnapshotjob 
  21140. --              at the publisher to set up a dynamic snapshot job in msdb
  21141. --              at the distributor. 
  21142. -- Notes: This procedure will only perform implicit checking for scheduling 
  21143. --        parameters as most parameters are expected to have been checked 
  21144. --        in sp_MSaddmergedynamicsnapshotjob
  21145. --
  21146. -- Parameters: @regular_snapshot_jobid uniqueidentifier (mandatory)
  21147. --             @dynamic_filter_login sysname (optional, default null)
  21148. --             @dynamic_filter_hostname sysname (optional, default null)
  21149. --             @dynamic_snapshot_location nvarchar(255) (mandatory)
  21150. --             @dynamic_snapshot_jobid uniqueidentifier (mandatory)
  21151. --             Scheduling information:
  21152. --             @freqtype int (optional, default 4 == Daily)
  21153. --             @freqinterval int (optional, default 1 == Every day)
  21154. --             @freqsubtype int (optional, default 4 (Sub interval = Minute))
  21155. --             @freqsubinterval int (optional, default 5 == Every five minutes)
  21156. --             @freqrelativeinterval int (optional, default 1) 
  21157. --             @freqrecurrencefactor int (optional, default 0) 
  21158. --             @activestartdate int (optional, default 0 == Today)
  21159. --             @activeenddate int (optional, default 99991231) 
  21160. --             @activestarttimeofday int (optional, default 0 == Now)        
  21161. --             @activeendtimeofday int (optional, default 235959)
  21162. --
  21163. -- Returns: 0 - succeeded
  21164. --          1 - failed
  21165. --
  21166. -- Security: Only members of the 'sysadmin' server role and members of the 
  21167. --           'db_owner' database role at the distributor can call this 
  21168. --           procedure. This procedure is intended to be called through 
  21169. --           the distributor_admin remote login in the case where
  21170. --           the distributor is a different machine from the publisher. 
  21171. --
  21172. create procedure sp_MSadddynamicsnapshotjobatdistributor (
  21173.     @regular_snapshot_jobid uniqueidentifier,
  21174.     @dynamic_filter_login sysname = null,
  21175.     @dynamic_filter_hostname sysname = null,
  21176.     @dynamic_snapshot_location nvarchar(255),
  21177.     @dynamic_snapshot_jobname sysname output,
  21178.     @dynamic_snapshot_jobid uniqueidentifier output,
  21179.  
  21180.     -- Scheduling information
  21181.     @freqtype               int = 4,
  21182.     @freqinterval           int = 1,
  21183.     @freqsubtype            int = 4,
  21184.     @freqsubinterval        int = 5,
  21185.     @freqrelativeinterval   int = 1, 
  21186.     @freqrecurrencefactor   int = 0,
  21187.     @activestartdate        int = 0,
  21188.     @activeenddate          int = 99991231,
  21189.     @activestarttimeofday   int = 0, 
  21190.     @activeendtimeofday     int = 235959
  21191.     )
  21192. as
  21193. begin
  21194.     set nocount on
  21195.  
  21196.     declare @retcode int
  21197.     declare @agent_command_line nvarchar(4000)
  21198.     declare @agent_id int
  21199.     declare @db_name sysname    
  21200.     declare @category_name sysname
  21201.     declare @nullchar nchar(20)
  21202.  
  21203.     declare @dynamicfilterloginparam nvarchar(50)
  21204.     declare @dynamicfilterhostnameparam nvarchar(50)
  21205.     declare @dynamicsnapshotlocationparam nvarchar(50)
  21206.     
  21207.     select @retcode = 0
  21208.     select @agent_command_line = null
  21209.     select @agent_id = null
  21210.     select @db_name = db_name()
  21211.     select @category_name = name 
  21212.       from msdb.dbo.syscategories 
  21213.      where category_id = 15
  21214.     select @nullchar = null
  21215.  
  21216.     select @dynamicfilterloginparam = N' -DynamicFilterLogin '
  21217.     select @dynamicfilterhostnameparam = N' -DynamicFilterHostName '
  21218.     select @dynamicsnapshotlocationparam = N' -DynamicSnapshotLocation '
  21219.  
  21220.     -- Get the regular snapshot agent command line
  21221.     select @agent_command_line = command 
  21222.       from msdb..sysjobsteps
  21223.      where job_id = @regular_snapshot_jobid
  21224.        and subsystem = N'Snapshot'
  21225.        and step_id = 2
  21226.         
  21227.     if @agent_command_line is null
  21228.     begin
  21229.         raiserror(21319, 11, -1)        
  21230.         return 1        
  21231.     end  
  21232.     
  21233.     -- Get the agent id    
  21234.     select @agent_id = id
  21235.       from MSsnapshot_agents
  21236.      where job_id = @regular_snapshot_jobid
  21237.  
  21238.     if @agent_id is null
  21239.     begin
  21240.         raiserror(21325, 11, -1)
  21241.         return 1
  21242.     end
  21243.  
  21244.     if @dynamic_snapshot_jobname is null or @dynamic_snapshot_jobname = N''
  21245.     begin
  21246.         -- Get the job name of the regular snapshot job. This is going to be used
  21247.         -- to derive a uniquefied job name for the dynamic snapshot job
  21248.         select @dynamic_snapshot_jobname = name 
  21249.           from msdb..sysjobs 
  21250.          where job_id = @regular_snapshot_jobid
  21251.     
  21252.         select @dynamic_snapshot_jobname = N'dyn_' + left(@dynamic_snapshot_jobname,88) + convert(nvarchar(36), newid()) 
  21253.     end
  21254.  
  21255.     if @dynamic_filter_login is not null and @dynamic_filter_login <> N''
  21256.     begin
  21257.         select @agent_command_line = @agent_command_line + @dynamicfilterloginparam + N'[' + rtrim(@dynamic_filter_login) + N']' 
  21258.     end
  21259.  
  21260.     if @dynamic_filter_hostname is not null and @dynamic_filter_hostname <> N''
  21261.     begin
  21262.         select @agent_command_line = @agent_command_line + @dynamicfilterhostnameparam + N'[' + rtrim(@dynamic_filter_hostname) + N']' 
  21263.     end
  21264.  
  21265.     -- @dynamic_snapshot_location is assumed to be non-empty
  21266.     select @agent_command_line = @agent_command_line + @dynamicsnapshotlocationparam + N'[' + @dynamic_snapshot_location + N']'
  21267.  
  21268.     -- Add the job
  21269.     exec @retcode = dbo.sp_MSadd_repl_job
  21270.          @name = @dynamic_snapshot_jobname,
  21271.          @subsystem = 'Snapshot',
  21272.          @server = @@servername,
  21273.          @databasename = @db_name,
  21274.          @enabled = 1,
  21275.          @freqtype = @freqtype,
  21276.          @freqinterval = @freqinterval,
  21277.          @freqsubtype = @freqsubtype,
  21278.          @freqsubinterval = @freqsubinterval,
  21279.          @freqrecurrencefactor = @freqrecurrencefactor,
  21280.          @activestartdate = @activestartdate,
  21281.          @activeenddate = @activeenddate,
  21282.          @activestarttimeofday = @activestarttimeofday,
  21283.          @activeendtimeofday = @activeendtimeofday,
  21284.          @nextrundate = 0,
  21285.          @nextruntime = 0,
  21286.          @runpriority = 0,
  21287.          @emailoperatorname = @nullchar,
  21288.          @retryattempts = 10,
  21289.          @retrydelay = 1,
  21290.          @command = @agent_command_line,
  21291.          @loghistcompletionlevel = 0,
  21292.          @emailcompletionlevel = 0,
  21293.          @description = @nullchar,
  21294.          @tagobjectid = 0,
  21295.          @tagobjecttype = 0,
  21296.          @category_name = @category_name,
  21297.          @failure_detection = 1,
  21298.          @agent_id = @agent_id,
  21299.          @job_id = @dynamic_snapshot_jobid output            
  21300.  
  21301.     return @retcode
  21302. end
  21303. go
  21304.  
  21305. raiserror(15339, -1, -1, 'sp_MSdeleterepljob')
  21306. go
  21307. --
  21308. -- Name: sp_MSdeleterepljob
  21309. --
  21310. -- Description: This is a lightweight wrapper of sp_delete_job to be used
  21311. --              by remote publishers.
  21312. --
  21313. -- Parameter: @job_id uniqueidentifier (mandatory)
  21314. --
  21315. -- Returns 0 - succeeded
  21316. --         1 - failed
  21317. -- 
  21318. -- Security: Only members of the sysadmin server role and members of the 
  21319. -- db_owner role of the distribution database can execute this function. This
  21320. -- procedure is intended to be called through the distribution_admin remote 
  21321. -- login from remote publishers
  21322. --
  21323. create procedure sp_MSdeleterepljob (
  21324.     @job_id uniqueidentifier
  21325.     )
  21326. as
  21327. begin
  21328.     set nocount on
  21329.     declare @retcode int
  21330.     declare @job_name sysname 
  21331.  
  21332.     select @retcode = 0
  21333.     exec @retcode = msdb..sp_delete_job @job_id = @job_id
  21334.  
  21335.     return @retcode
  21336. end
  21337. go
  21338.  
  21339. raiserror(15339, -1, -1, 'sp_MSdeletefoldercontents')
  21340. go
  21341. --
  21342. -- Name: sp_MSdeletefoldercontents
  21343. --
  21344. -- Description: This is a lighweight wrapper for deleting all files in the
  21345. --              specified directory. This procedure is meant to be called by 
  21346. --              a remote publisher for deleting files in the distributor's 
  21347. --              context.
  21348. --
  21349. -- Parameter: @folder nvarchar(255) (mandatory)
  21350. --
  21351. -- Returns 0 - succeeded
  21352. --         1 - failed
  21353. --
  21354. -- Security: Only members of the sysadmin server role and members of the 
  21355. -- db_owner role of the distribution database can execute this function. This
  21356. -- procedure is intended to be called through the distribution_admin remote 
  21357. -- login from remote publishers
  21358. --
  21359. create procedure sp_MSdeletefoldercontents (
  21360.     @folder nvarchar(255)
  21361.     )
  21362. as
  21363. begin
  21364.     set nocount on
  21365.  
  21366.     declare @command nvarchar(4000)
  21367.     declare @retcode int
  21368.  
  21369.     select @retcode = 0
  21370.     if len(@folder) = 0 or @folder is null
  21371.     begin
  21372.         return 0
  21373.     end
  21374.  
  21375.     -- Append '\*' to the given path 
  21376.     if substring(@folder, len(@folder), 1) <> N'\'
  21377.     begin
  21378.         select @folder = @folder + N'\'
  21379.     end 
  21380.  
  21381.     select @folder = @folder + '*'    
  21382.  
  21383.     if (platform() & 0x1) = 0x1 
  21384.     begin
  21385.         select @command = 'del /q /f "' + fn_escapecmdshellsymbolsremovequotes(@folder) collate database_default + '"'
  21386.     end
  21387.     else
  21388.     begin
  21389.         -- Win9x 'del' command does not support the /q and /f switches
  21390.         select @command = 'del "' + fn_escapecmdshellsymbolsremovequotes(@folder) collate database_default + '.*"'
  21391.     end
  21392.  
  21393.     exec @retcode = master..xp_cmdshell @command, no_output
  21394.     return @retcode
  21395.  
  21396. end
  21397. go
  21398.  
  21399. CREATE PROCEDURE sp_MSinvalidate_snapshot
  21400. @publisher sysname,
  21401. @publisher_db sysname,
  21402. @publication sysname
  21403.  
  21404. as
  21405.     set nocount on
  21406.     declare @publisher_id smallint  
  21407.     declare @automatic tinyint
  21408.     declare @virtual smallint 
  21409.     declare @retcode int
  21410.     declare @active tinyint
  21411.         , @initiated tinyint
  21412.         , @subscribed tinyint
  21413.     declare @publication_id int
  21414.  
  21415.     select @automatic = 1
  21416.     select @virtual = - 1
  21417.     select @active = 2
  21418.         , @initiated = 3
  21419.         , @subscribed = 1
  21420.  
  21421.     -- Check if publisher is a defined as a distribution publisher in the current database
  21422.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  21423.     if @retcode <> 0
  21424.     begin
  21425.         return(1)
  21426.     end
  21427.  
  21428.     -- Make sure publication exists
  21429.     select @publication_id = publication_id
  21430.         from MSpublications where publication = @publication and
  21431.         publisher_id = @publisher_id and publisher_db = @publisher_db
  21432.  
  21433.     -- Set the virtual subscription status to be 'subscribed' so that
  21434.     -- new subscription will wait for the next snapshot.
  21435.     update MSsubscriptions set status = @subscribed where 
  21436.         publication_id = @publication_id and
  21437.         sync_type = @automatic and
  21438.         status in (@active, @initiated) and
  21439.         subscriber_id = @virtual
  21440.  
  21441.     return (0)
  21442. GO
  21443.  
  21444. create procedure sp_MSrepl_init_backup_lsns
  21445. as
  21446.     -- The stored procedure is called by sp_replicationoption when changing a dist
  21447.     -- db to 'sync with backup' mode
  21448.     set nocount on
  21449.     
  21450.     -- Set the truncate lsns to null. By doing this
  21451.     -- the distribution agent will stop calling sp_repldone untill a dist db
  21452.     -- backup is done.
  21453.     update MSrepl_backup_lsns set valid_xact_seqno = NULL,
  21454.         valid_xact_id = NULL
  21455.     if @@error <> 0
  21456.         return 1
  21457.     return 0
  21458. go
  21459.  
  21460. --
  21461. -- Name: sp_MSispublicationqueued
  21462. --
  21463. -- Description: This procedure is invoked by sp_MShelp_replication_status 
  21464. --                to find out if the specified publication supports queued
  21465. --                updating subscribers. 
  21466. --
  21467. -- Parameter: 
  21468. --                @publisher sysname (mandatory)
  21469. --                @publisher_db sysname (mandatory)
  21470. --                @publication sysname (mandatory)
  21471. --                @allow_queued_tran bit OUTPUT (mandatory)
  21472. --
  21473. -- Returns 0 - succeeded
  21474. --         1 - failed
  21475. --
  21476. -- Security: Only members of the sysadmin server role and members of the 
  21477. -- db_owner role of the distribution database can execute this function.
  21478. --
  21479. raiserror(15339,-1,-1,'sp_MSispublicationqueued')
  21480. go
  21481. create procedure sp_MSispublicationqueued (
  21482.     @publisher sysname
  21483.     ,@publisher_db sysname
  21484.     ,@publication sysname
  21485.     ,@allow_queued_tran bit OUTPUT
  21486.     )
  21487. as
  21488. begin
  21489.     --
  21490.     -- get the queued tran state for the publication
  21491.     --
  21492.     if exists (select * from dbo.sysobjects where name = N'MSpublications')
  21493.     begin
  21494.         select @allow_queued_tran = pub.allow_queued_tran 
  21495.         from (dbo.MSpublications as pub join master.dbo.sysservers as srv
  21496.                 on pub.publisher_id = srv.srvid)
  21497.         where UPPER(srv.srvname) = UPPER(@publisher)
  21498.             and pub.publisher_db = @publisher_db
  21499.             and pub.publication = @publication
  21500.     end
  21501.     else
  21502.         select @allow_queued_tran = 0
  21503.  
  21504.     --
  21505.     -- all done
  21506.     --
  21507.     return 0
  21508. end
  21509. go
  21510.  
  21511. raiserror(15339,-1,-1,'sp_MSlog_agent_cancel')
  21512. go
  21513. create procedure sp_MSlog_agent_cancel
  21514. @job_id binary(16),
  21515. @category_id int,
  21516. @message nvarchar(1024)
  21517. as
  21518.     -- This stored procedure is called by msdb proc, sp_sqlagent_log_jobhistory to
  21519.     -- log a agent cancel message to repl monitor (agent history tables) when the
  21520.     -- agent fails to log a complete message to repl monitor directly. 
  21521.     -- sp_MSdetect_nonlogged_shutdown would not help in this case, because that step
  21522.     -- will not be executed because the job is canceled before the step.
  21523.     declare @agent_id int
  21524.  
  21525.     if @category_id = 15
  21526.     begin
  21527.         -- Get agent_id
  21528.         select @agent_id = id from MSsnapshot_agents where job_id = @job_id
  21529.         if exists (select runstatus from MSsnapshot_history where 
  21530.             agent_id = @agent_id and
  21531.             runstatus <> 2 and 
  21532.             runstatus <> 5 and 
  21533.             runstatus <> 6 and
  21534.             timestamp = (select max(timestamp) from MSsnapshot_history where agent_id = @agent_id))
  21535.         begin
  21536.             -- Log success message.
  21537.             exec dbo.sp_MSadd_snapshot_history @agent_id = @agent_id, @runstatus = 2,
  21538.                     @comments = @message
  21539.         end
  21540.     end
  21541.     else if @category_id = 13
  21542.     begin
  21543.         -- Get agent_id
  21544.         select @agent_id = id from MSlogreader_agents where job_id = @job_id
  21545.         if exists (select runstatus from MSlogreader_history where 
  21546.             agent_id = @agent_id and
  21547.             runstatus <> 2 and 
  21548.             runstatus <> 5 and 
  21549.             runstatus <> 6 and
  21550.             timestamp = (select max(timestamp) from MSlogreader_history where agent_id = @agent_id))
  21551.             begin
  21552.                 -- Log success message.
  21553.                 exec dbo.sp_MSadd_logreader_history @agent_id = @agent_id, @runstatus = 2,
  21554.                         @comments = @message
  21555.             end
  21556.     end
  21557.     else if @category_id = 10
  21558.     begin
  21559.         -- Get agent_id
  21560.         select @agent_id = id from MSdistribution_agents where job_id = @job_id
  21561.         if exists (select runstatus from MSdistribution_history where 
  21562.             agent_id = @agent_id and
  21563.             runstatus <> 2 and 
  21564.             runstatus <> 5 and 
  21565.             runstatus <> 6 and
  21566.             timestamp = (select max(timestamp) from MSdistribution_history where agent_id = @agent_id))
  21567.             begin
  21568.                 -- Log success message.
  21569.                 exec dbo.sp_MSadd_distribution_history @agent_id = @agent_id, @runstatus = 2,
  21570.                         @comments = @message
  21571.             end
  21572.     end
  21573.     else if @category_id = 14
  21574.     begin
  21575.         -- Get agent_id
  21576.         select @agent_id = id from MSmerge_agents where job_id = @job_id
  21577.         if exists (select runstatus from MSmerge_history where 
  21578.             agent_id = @agent_id and
  21579.             runstatus <> 2 and 
  21580.             runstatus <> 5 and 
  21581.             runstatus <> 6 and
  21582.             timestamp = (select max(timestamp) from MSmerge_history where agent_id = @agent_id))
  21583.             begin
  21584.                 -- Log success message.
  21585.                 exec dbo.sp_MSadd_merge_history @agent_id = @agent_id, @runstatus = 2,
  21586.                         @comments = @message
  21587.             end
  21588.     end
  21589.     else if @category_id = 19
  21590.     begin
  21591.         -- Get agent_id
  21592.         select @agent_id = id from MSqreader_agents where job_id = @job_id
  21593.         if exists (select runstatus from MSqreader_history where 
  21594.             agent_id = @agent_id and
  21595.             runstatus <> 2 and 
  21596.             runstatus <> 5 and 
  21597.             runstatus <> 6 and
  21598.             timestamp = (select max(timestamp) from MSqreader_history where agent_id = @agent_id))
  21599.             begin
  21600.                 -- Log success message.
  21601.                 exec dbo.sp_MSadd_qreader_history @agent_id = @agent_id, @runstatus = 2,
  21602.                         @comments = @message
  21603.             end
  21604.     end
  21605.  
  21606. GO
  21607.  
  21608. create procedure sp_MSwritemergeperfcounter (
  21609.     @agent_id int,
  21610.     @thread_num int,
  21611.     @counter_desc nvarchar(100),
  21612.     @counter_value int
  21613.     )
  21614. AS
  21615.     if (not exists (select * from sysobjects where name = 'MSmerge_perfcounters'))
  21616.     begin
  21617.         create table MSmerge_perfcounters
  21618.         (
  21619.             agent_id int NOT NULL,
  21620.             thread_num int NULL,
  21621.             counter_desc nvarchar(100) NOT NULL,
  21622.             counter_value int NOT NULL,
  21623.             cur_time datetime NOT NULL
  21624.         )
  21625.     end
  21626.  
  21627.     insert into MSmerge_perfcounters values (@agent_id, @thread_num, @counter_desc, @counter_value, getdate())
  21628.  
  21629.     return 0
  21630. go
  21631. EXEC dbo.sp_MS_marksystemobject 'sp_MSwritemergeperfcounter'
  21632. go
  21633. grant execute on sp_MSwritemergeperfcounter to public
  21634. go
  21635.  
  21636. go
  21637.  
  21638. /****************************************************************************/
  21639. print ''
  21640. print 'Adding user ''guest''.'
  21641. print ''
  21642. /****************************************************************************/
  21643. if not exists (select * from sysusers where
  21644.     name = N'guest' and
  21645.     hasdbaccess = 1)
  21646.     EXEC  dbo.sp_adduser 'guest'
  21647.  
  21648. /****************************************************************************/
  21649. print ''
  21650. print 'Adding role ''replmonitor''.'
  21651. print ''
  21652. /****************************************************************************/
  21653. if not exists (select * from sysusers where
  21654.     name = N'replmonitor' and
  21655.     issqlrole = 1)
  21656.     EXEC  dbo.sp_addrole 'replmonitor'
  21657.  
  21658.  
  21659. grant execute on dbo.sp_MSdistribution_counters to public
  21660. GO 
  21661. grant execute on dbo.sp_MShelp_profile to public
  21662. GO
  21663. grant execute on dbo.sp_MShelp_subscriber_info to public
  21664. GO
  21665.  
  21666.  
  21667. /* 
  21668. Stored procedures called by dist publisher.
  21669. distributor_admin will be added to db_owner role. Members of
  21670. db_owner have permission on all the stored procedures. 
  21671.  
  21672. -- Stored procedure used by remote publisher RPC
  21673. grant execute on dbo.sp_MSbrowsesnapshotfolder to db_owner
  21674. grant execute on dbo.sp_MSadd_publication to db_owner
  21675. grant execute on dbo.sp_MSchange_publication to db_owner
  21676. grant execute on dbo.sp_MSdrop_publication to db_owner
  21677. grant execute on dbo.sp_MSadd_article to db_owner
  21678. grant execute on dbo.sp_MSchange_article to db_owner
  21679. grant execute on dbo.sp_MSdrop_article to db_owner
  21680. grant execute on dbo.sp_MSadd_subscriber_info to db_owner
  21681. grant execute on dbo.sp_MSupdate_subscriber_info to db_owner
  21682. grant execute on dbo.sp_MSadd_subscriber_schedule to db_owner
  21683. grant execute on dbo.sp_MSupdate_subscriber_schedule to db_owner
  21684. grant execute on dbo.sp_MShelp_subscriber_info to db_owner
  21685. grant execute on dbo.sp_MSdrop_subscriber_info to db_owner
  21686. grant execute on dbo.sp_MSadd_snapshot_agent to db_owner
  21687. grant execute on dbo.sp_MSdrop_snapshot_agent to db_owner
  21688. grant execute on dbo.sp_MSadd_logreader_agent to db_owner
  21689. grant execute on dbo.sp_MSdrop_logreader_agent to db_owner
  21690. grant execute on dbo.sp_MSreset_subscription to db_owner
  21691. grant execute on dbo.sp_MSenableagentoffload to db_owner
  21692. grant execute on dbo.sp_MSdisableagentoffload to db_owner
  21693. grant execute on dbo.sp_MSinsert_identity to db_owner
  21694. grant execute on dbo.sp_MSadjust_pub_identity to db_owner
  21695. grant execute on dbo.sp_MScheck_pub_identity to db_owner
  21696. grant execute on dbo.sp_MSadddynamicsnapshotjobatdistributor to db_owner
  21697. grant execute on dbo.sp_MSdrop_repl_job to db_owner
  21698. -- Stored procedure used by snapshot and logreader agents
  21699. grant execute on dbo.sp_MSadd_repl_command to db_owner
  21700. grant execute on dbo.sp_MSadd_repl_commands27 to db_owner
  21701. grant execute on dbo.sp_MSadd_repl_commands27hp to db_owner
  21702. grant execute on dbo.sp_MSadd_repl_commands27hp6x to db_owner
  21703. grant execute on dbo.sp_MSget_last_transaction to db_owner
  21704. grant execute on dbo.sp_MSset_snapshot_xact_seqno to db_owner
  21705. grant execute on dbo.sp_MSadd_snapshot_history to db_owner
  21706. grant execute on dbo.sp_MSadd_logreader_history to db_owner
  21707. grant execute on dbo.sp_MSdist_activate_auto_sub to db_owner
  21708. grant execute on dbo.sp_MSlock_auto_sub to db_owner
  21709. grant execute on dbo.sp_MSget_new_xact_seqno to db_owner
  21710. grant execute on dbo.sp_MSactivate_subscriptions to db_owner
  21711. grant execute on dbo.sp_MShelp_snapshot_agentid to db_owner
  21712. grant execute on dbo.sp_MShelp_logreader_agentid to db_owner
  21713. grant execute on dbo.sp_MSadd_subscription to public
  21714. grant execute on dbo.sp_MSupdate_subscription to public
  21715. grant execute on dbo.sp_MSdrop_subscription to public
  21716. grant execute on dbo.sp_MSadd_merge_subscription to public
  21717. grant execute on dbo.sp_MSdrop_merge_subscription to public
  21718. */
  21719.  
  21720.  
  21721.  
  21722. -- Stored procedures used by dist and merge agents. They are granted to public
  21723.  
  21724. grant execute on dbo.sp_MSmarkreinit to public
  21725. go
  21726.  
  21727. -- Procedures to retrieve actual data. Need security check inside
  21728. grant execute on dbo.sp_MSget_repl_commands to public
  21729. GO
  21730. grant execute on dbo.sp_MSget_repl_cmds_anonymous to public
  21731. GO
  21732.  
  21733. -- Procedures to modify meta data. Need security check inside.
  21734. grant execute on dbo.sp_MSadd_distribution_history to public
  21735. grant execute on dbo.sp_MSadd_repl_error to public
  21736. grant execute on dbo.sp_MSadd_repl_alert to public
  21737. grant execute on dbo.sp_MSadd_replmergealert to public
  21738. grant execute on dbo.sp_MSadd_merge_history to public
  21739. grant execute on dbo.sp_MSadd_anonymous_agent to public
  21740. grant execute on dbo.sp_MSadd_merge_anonymous_agent to public
  21741. grant execute on dbo.sp_MSdist_adjust_identity to public
  21742. GO
  21743.  
  21744. -- Procedures to retrieve meta data. No security check inside.
  21745. grant execute on dbo.sp_MSget_subscription_guid to public
  21746. grant execute on dbo.sp_MSreset_subscription_seqno to public
  21747. grant execute on dbo.sp_MSanonymous_status to public
  21748. grant execute on dbo.sp_MSsubscription_status to public
  21749. grant execute on dbo.sp_MShelp_merge_agentid to public
  21750. grant execute on dbo.sp_MScheckretention to public
  21751. grant execute on dbo.sp_MShelp_distribution_agentid to public
  21752. grant execute on dbo.sp_MScheck_tran_retention to public
  21753. grant execute on dbo.sp_MSgetagentoffloadinfo to public
  21754. grant execute on dbo.sp_MSenumdistributionagentproperties to public
  21755. grant execute on dbo.sp_MSenum_merge_agent_properties to public
  21756. grant execute on dbo.sp_MSrepl_raiserror to public
  21757. -- sp_MShelp_publication is used by the distribution control add anonymous
  21758. -- subscription logic to ascertain the existence of a publication 
  21759. grant execute on dbo.sp_MShelp_publication to public
  21760. -- sp_MSenum_replication_status to load repl monitor status table
  21761. -- The status table is global and shared by all users. A user in
  21762. -- replmonitor role in any dist db may load the table, the proc
  21763. -- has to be granted to public.
  21764. grant execute on sp_MSenum_replication_status to public
  21765. go
  21766.  
  21767. -- grant monitoring sps to replmonitor
  21768. GRANT exec on sp_MShelp_publication to replmonitor 
  21769. GRANT exec on sp_MSenum_subscriptions to replmonitor 
  21770. GRANT exec on sp_MSIfExistsSubscription to replmonitor 
  21771. GRANT exec on sp_MSenum_merge_subscriptions to replmonitor 
  21772. GRANT exec on sp_MSenum_distribution to replmonitor 
  21773. GRANT exec on sp_MSenum_merge to replmonitor 
  21774. GRANT exec on sp_MSenum_snapshot to replmonitor 
  21775. GRANT exec on sp_MSenum_logreader to replmonitor
  21776. GRANT exec on sp_MSenum_qreader to replmonitor 
  21777. GRANT exec on sp_MSenum_snapshot_s to replmonitor 
  21778. GRANT exec on sp_MSenum_logreader_s to replmonitor
  21779. GRANT exec on sp_MSenum_distribution_s to replmonitor
  21780. GRANT exec on sp_MSenum_merge_s to replmonitor 
  21781. GRANT exec on sp_MSenum_qreader_s to replmonitor 
  21782. GRANT exec on sp_MSenum_snapshot_sd to replmonitor 
  21783. GRANT exec on sp_MSenum_logreader_sd to replmonitor
  21784. GRANT exec on sp_MSenum_distribution_sd to replmonitor
  21785. GRANT exec on sp_MSenum_merge_sd to replmonitor
  21786. GRANT exec on sp_MSenum_qreader_sd to replmonitor
  21787. GRANT exec on sp_MSget_repl_error to replmonitor
  21788. go
  21789.  
  21790.  
  21791. declare @dbname sysname
  21792. select  @dbname = db_name()
  21793. execute('dump transaction ' +@dbname+ ' with no_log')
  21794. go
  21795. checkpoint
  21796.  
  21797. go
  21798.  
  21799. exec dbo.sp_MS_upd_sysobj_category 2  --Now do catalog updates.
  21800.  
  21801. go
  21802.  
  21803. EXEC dbo.sp_configure 'allow updates', 0
  21804. GO
  21805.  
  21806. reconfigure with override
  21807. GO
  21808. -- - ----
  21809.